# Credits Staging Recovery Runbook 2026-06-03

## Goal

When staging is rebuilt, restore `Credits__c` / `Credits_Topup__c` quickly to the currently verified working state that exists in prod.

This runbook records only the path that was actually validated.

## Current Verified Baseline

Verified in prod:

- objects
  - `Credits__c`
  - `Credits_Topup__c`
- actions
  - `Account.ApplyForCredits`
  - `Opportunity.ApplyForPoCCredits`
  - `Credits__c.AddCreditsTopup`
- layout
  - `Credits Layout`
  - `Top-ups` related list present
- approval processes
  - `PoC_Credits_Approval_Process`
  - `Credits_Topup_Approval_Process`
- parent-object flows
  - `Credits_Hint_Available_Cloud_Orgs`
  - `Credits_Lifecycle_On_Approval_Decision`
  - `Credits_Prefill_Snapshot_Fields`
  - `Credits_Stamp_Approvers`
  - `Credits_Stamp_Approvers_Retry`
  - `Credits_Stamp_Completed_Date`
- top-up relationship metadata
  - `Credits_Topup__c.Credits__c`
  - `RelationshipName = Credits__r`
  - `ChildRelationshipName = Topups`

## SQL To Run

Run these in order:

1. schema

```text
docs/migration/patch-bundles/20260531_staging_green_customsetting_column/004_region_all_and_credits_schema.sql
```

2. metadata

```text
docs/migration/patch-bundles/20260531_staging_green_customsetting_column/005_region_all_and_credits_metadata.sql
```

3. layout / actions / parent flows / validation rules

```text
docs/migration/patch-bundles/20260531_staging_green_customsetting_column/006_credits_surface_and_flows.sql
```

4. approval / permissions

```text
docs/migration/patch-bundles/20260531_staging_green_customsetting_column/007_credits_approval_and_permissions.sql
```

5. cloud-org hint enhancement

```text
docs/migration/patch-bundles/20260601_lead_setcountrycodefromcountry_flow_update/002_apply_pr2265_credits_hint_available_cloud_orgs.sql
```

6. top-up parent relationship fix

```text
docs/migration/patch-bundles/20260603_credits_topup_relationship_fix/001_fix_credits_topup_parent_relationship.sql
```

## Do Not Run

Do not run this revert script during recovery:

```text
docs/migration/patch-bundles/20260601_lead_setcountrycodefromcountry_flow_update/003_revert_pr2265_credits_hint_available_cloud_orgs.sql
```

Reason:

- current prod baseline includes `Credits_Hint_Available_Cloud_Orgs`
- staging recovery should converge to current prod baseline, not remove it

## Relationship Fix SQL

This was executed and verified on both staging and prod:

```sql
UPDATE `_System_Field` AS f
JOIN `_System_Object` AS o
  ON o.`Id` = f.`ObjectId`
SET
  f.`RelationshipName` = 'Credits__r',
  f.`ChildRelationshipName` = 'Topups',
  f.`LastModifiedDate` = NOW()
WHERE o.`ApiName` = 'Credits_Topup__c'
  AND f.`ApiName` = 'Credits__c'
  AND f.`OwnerPack` = 'salesforce-crm-standard'
  AND f.`IsDeleted` = 0;
```

## Verification SQL

### Objects

```sql
SELECT ApiName, Label, SharingModel, IsDeleted
FROM `_System_Object`
WHERE ApiName IN ('Credits__c','Credits_Topup__c')
ORDER BY ApiName;
```

### Actions

```sql
SELECT ObjectApiName, Name, Label, Type, TargetObject, IsDeleted, OwnerPack
FROM `_System_Action`
WHERE TargetObject='Credits__c' OR ObjectApiName='Credits__c'
ORDER BY ObjectApiName, Name;
```

### Approval Processes

```sql
SELECT DeveloperName, Name, State, TableEnumOrId, IsActive, OwnerPack
FROM `ProcessDefinition`
WHERE TableEnumOrId IN ('Credits__c','Credits_Topup__c')
ORDER BY TableEnumOrId, DeveloperName;
```

### Flows

```sql
SELECT DeveloperName, MasterLabel, TriggerObjectOrEvent, ProcessType, TriggerType, OwnerPack
FROM `FlowDefinition`
WHERE TriggerObjectOrEvent IN ('Credits__c','Credits_Topup__c')
ORDER BY TriggerObjectOrEvent, DeveloperName;
```

### Layout / Related Lists

```sql
SELECT Id, LayoutName,
       JSON_EXTRACT(Config, '$.quickActions') AS quickActions,
       JSON_EXTRACT(Config, '$.headerActions') AS headerActions,
       JSON_EXTRACT(Config, '$.relatedLists') AS relatedLists
FROM `_System_PageLayout`
WHERE ObjectApiName='Credits__c';
```

### Top-up Relationship Metadata

```sql
SELECT o.ApiName AS ObjectApiName, f.ApiName, f.Type,
       f.RelationshipName, f.ChildRelationshipName, f.OwnerPack
FROM `_System_Field` f
JOIN `_System_Object` o ON o.Id=f.ObjectId
WHERE o.ApiName='Credits_Topup__c'
  AND f.ApiName='Credits__c';
```

Expected:

```text
RelationshipName = Credits__r
ChildRelationshipName = Topups
```

## API Verification

Login:

```text
https://nexuscrm-new-staging.pingcap.com
admin@example.invalid / NexusCRM!Offline2026#Safe
```

### SOQL Validation For `Credits.Name`

The query must return normally. `totalSize = 0` is acceptable. The only failure condition here is the previous relationship resolution error.

```text
/services/data/v63.0/query?q=SELECT Id, Topup_Sequence__c, Topup_Amount__c, Cumulative_Disbursed__c, Approval_Status__c, Credits__c, Name, Credits.Name FROM Credits_Topup__c WHERE (Credits__c = '6e78ed4d-1199-4ed7-bcf3-8f8f2a8fc319') ORDER BY CreatedDate DESC LIMIT 20
```

### record-ui Validation

```text
/services/data/v63.0/ui-api/record-ui/6e78ed4d-1199-4ed7-bcf3-8f8f2a8fc319?type=Credits__c
```

### Page Validation

Open:

```text
https://nexuscrm-new-staging.pingcap.com/object/Credits__c/6e78ed4d-1199-4ed7-bcf3-8f8f2a8fc319
```

Check:

- page opens
- `Add Top-up` button is present
- `Top-ups` related list no longer throws the `Credits.Name` relationship error

## Cache Refresh

If SQL has landed but the page still reads stale metadata, refresh caches.

Use the standard rebuild / refresh metadata / refresh cache path for staging.

## Scope Note

This runbook restores the currently verified working credits baseline.

It does not claim that every planned `Credits_Topup__c` extension flow exists in the pack today. Recovery target is current verified prod baseline, not every earlier design-thread idea.
