# L2 UI Pack Guide

## Purpose

This guide is for downstream application engineers who want to put their own
UI shape into the PingCAP pack, then validate that shape through the standard
independent local deployment scripts and remote CI deploy flow.

The goal is:

1. edit the right downstream L2-facing metadata inputs
2. assemble those inputs into the final installable pack
3. verify the result locally when needed
4. deploy the result into a supported shared Test environment through CI

## Repository Split

Two repositories participate in the final environment:

1. upstream `NexusCRM`
   - runtime/platform authority
2. official app-pack repo `nexuscrm-app-packs`
   - official standard CRM pack authority
3. downstream `nexuscrm-pingcap-pack`
   - PingCAP-specific metadata inputs
   - final pack assembly
   - bootstrap/deploy orchestration

Hard rule:

- do not put PingCAP-specific UI behavior into upstream unless it is truly
  generic platform or generic standard CRM behavior

## Source Of Truth

For downstream UI work, the source-of-truth chain is:

1. upstream ref, defaulting to `main`
2. official `salesforce-crm-standard` ref, defaulting to `main`
3. downstream checked-in inputs under `packs/Salesforce-PingCAP-L2`
4. assembled final pack under `packs/NOT-EDIT-final-merged-packs`

Hard rules:

1. `packs/Salesforce-PingCAP-L2` is the editable downstream input
2. `packs/NOT-EDIT-final-merged-packs` is the installable artifact
3. do not hand-edit `packs/NOT-EDIT-final-merged-packs`
4. after changing downstream inputs, regenerate the final pack

## What To Edit

Typical UI-facing files live under:

```text
packs/Salesforce-PingCAP-L2/layouts/
packs/Salesforce-PingCAP-L2/ux/
packs/Salesforce-PingCAP-L2/actions/
packs/Salesforce-PingCAP-L2/related_lists/
packs/Salesforce-PingCAP-L2/record_types/
packs/Salesforce-PingCAP-L2/validation/
packs/Salesforce-PingCAP-L2/flows/
packs/Salesforce-PingCAP-L2/objects/
```

Use this mapping:

1. page layout changes
   - edit `packs/Salesforce-PingCAP-L2/layouts/*.json`
2. list page / list field changes
   - edit `packs/Salesforce-PingCAP-L2/ux/*.json`
3. record action / button changes
   - edit `packs/Salesforce-PingCAP-L2/actions/*.json`
4. related-list behavior changes
   - edit `packs/Salesforce-PingCAP-L2/related_lists/*.json`
5. record type driven UI differences
   - edit `packs/Salesforce-PingCAP-L2/record_types/*.json`
6. validation or flow that changes UI behavior
   - edit `packs/Salesforce-PingCAP-L2/validation/*.json`
   - edit `packs/Salesforce-PingCAP-L2/flows/*.json`
7. field visibility / labels / requiredness / options that affect UI
   - edit the relevant object under `packs/Salesforce-PingCAP-L2/objects/*.json`

If your change is about application navigation or shell-level entrypoints,
also check:

```text
stack.lock.json -> app_shell_config
configs/pingcap-crm-app-shell.json
```

That config is applied during local App installation and remote deploy and
controls the visible app shell/navigation contract for this stack.

## What Not To Edit

Do not use these files as your primary editing surface:

1. `packs/NOT-EDIT-final-merged-packs/**`
2. `.runtime/**`
3. `.tmp/**`
4. files copied into an upstream runtime worktree

Those are generated or runtime-only artifacts.

## Standard Working Flow

### 1. Create a worktree

All tracked changes must happen in an isolated worktree.

Example:

```bash
git worktree add .worktrees/<your-branch> -b <your-branch> origin/main
cd .worktrees/<your-branch>
```

### 2. Edit downstream metadata inputs

Change the relevant files under `packs/Salesforce-PingCAP-L2`.

Common examples:

```text
layouts/account_page_layout.json
layouts/opportunity_page_layout.json
ux/standard_listfields.json
actions/ui_actions.json
objects/Account.json
validation/standard_validation_rules.json
flows/Std_*.flow.json
```

> **`actions/ui_actions.json` is merged additively, not whole-file replaced.**
> The assembly (`merge_ui_action_payloads`) unions the official (L1) actions with
> this downstream file, keyed by `(object scope, name)`; L2 entries add new
> actions or override an official one by matching key. So author **only**
> tenant-specific actions and deliberate overrides here — do **not** re-copy the
> L1 standard actions (that would be redundant, and previously masked L1 fixes).
> To drop an official action, add a marker entry
> `{ "name": "<OfficialName>", "objectApiName": "<Object>", "suppress": true }`
> (omit `objectApiName`/`appliesTo` to suppress by name across all scopes). A
> suppress marker that matches no official action fails the build (fail-closed).

### 3. Regenerate the final pack

After editing downstream inputs:

```bash
bash scripts/build_pingcap_salesforce_sample_pack.sh --reset
```

Expected result:

1. `packs/NOT-EDIT-final-merged-packs/pack.json` is refreshed
2. `packs/NOT-EDIT-final-merged-packs/objects/standard_objects_spec.json` is refreshed
3. `packs/NOT-EDIT-final-merged-packs/.build-lineage.json` is refreshed

### 4. Sanity-check the assembled artifact

Minimum checks:

```bash
jq '.name' packs/NOT-EDIT-final-merged-packs/pack.json
jq '[.components[] | select(.kind=="object_spec")] | length' packs/NOT-EDIT-final-merged-packs/pack.json
```

Current expected contract:

1. final pack name should remain `salesforce-crm-standard`
2. final pack should expose exactly one `object_spec`
3. that object spec path should be `objects/standard_objects_spec.json`

### 5. Optional local verification

Follow [Independent local deployment](local-independent-deployment.md). Install
the assembled pack with the intended AppRelease/settings and local images,
then verify the intended API and browser journey after L0 activation and L1
deployment. Record inputs and results; local first installation does not prove
remote upgrade or release acceptance.

### 6. Commit both input and generated output

For UI changes that should affect remote deploy, commit:

1. your edited files under `packs/Salesforce-PingCAP-L2`
2. the regenerated files under `packs/NOT-EDIT-final-merged-packs`
3. any supporting docs or config updates

Do not commit runtime-only artifacts under `.runtime/` or `.tmp/`.

## Remote Validation

Use `docs/stack-test-model.md` and the selected workflow file as the current
authority for remote deployment topology and inputs.

## Definition Of Done For UI Pack Changes

Treat a UI pack change as ready only when all of these are true:

1. downstream editable source is updated
2. final assembled pack is regenerated
3. the final pack still follows the current upstream contract
4. local verification passes, or you intentionally skip local verification
5. remote CI deploy reaches a healthy environment
6. the expected screen/behavior is visible in the deployed site

## Quick Checklist

Before opening a PR:

1. did I edit `packs/Salesforce-PingCAP-L2`, not `packs/NOT-EDIT-final-merged-packs`?
2. did I rerun `bash scripts/build_pingcap_salesforce_sample_pack.sh --reset`?
3. did I confirm the final pack still has exactly one `object_spec`?
4. did I avoid committing `.runtime/**`, `.tmp/**`, or local secrets?
5. did I document how to verify the UI change?
6. did I trigger CI with the right `downstream_ref` and `upstream_ref`?

## Escalation Rule

Send the fix upstream instead of forcing it into downstream when:

1. the runtime cannot interpret your metadata
2. the standard pack contract changed
3. a generic setup/install/deploy behavior is broken
4. the same UI capability would be needed by multiple downstream packs
