# API Coverage Matrix for `#2152` / `#2165`

This matrix tracks what the downstream API watchdog currently proves for the R21 manual/UAT bundle:

- issue `#2152`: regression rollup
- issue `#2165`: detailed UAT scenarios

Scope here is **API watchdog only**. Browser-only assertions are called out explicitly instead of being over-claimed.

## Coverage Reading

| Status | Meaning |
|---|---|
| `covered` | current API watchdog has direct executable proof for the business contract |
| `partial` | API watchdog proves an important backend slice, but not the full UAT assertion |
| `not-api-suitable` | this is primarily UI/browser affordance and should not be claimed by API |
| `known-bug` | product bug is confirmed manually; watchdog should not convert it into a passing case |
| `blocked-by-product` | downstream passing automation would require the product gap to close first |

## Story `#773` Quote Line Items

| UAT point | API status | Watchdog case(s) | Note |
|---|---|---|---|
| Quote name shows business number, not raw id | `covered` | `quote-create-contract-api`, `quote-line-item-readable-reference-contract-api` | asserts `Name == QuoteNumber` and business-number format |
| QLI list has rows | `covered` | `quote-line-items-api`, `quote-create-line-item-clone-count-contract-api` | proves seeded and create-path QLI rows exist |
| Product2 shows readable product name | `covered` | `quote-line-item-readable-reference-contract-api` | proves relationship surface plus readable product strings |
| Price Book Entry shows readable name | `covered` | `quote-line-item-readable-reference-contract-api` | same for `PricebookEntry.Name` |
| Sales Price / Quantity / Discount / Net Fees contract | `partial` | `quote-line-item-pricing-contract-api` | API proves pricing/count basics, but not every list-column rendering detail |
| Net Fees and Net Fees (Total) both displayed and sync | `partial` | existing QLI API cases | backend row shape is covered; dual-field page rendering is browser-only |
| No raw UUID visible on page title/detail | `partial` | `quote-line-item-readable-reference-contract-api` | API proves readable naming contract, not exact page-title rendering |

## Story `#771` Quote Approval

| UAT point | API status | Watchdog case(s) | Note |
|---|---|---|---|
| Submit succeeds without entryCriteria error | `covered` | `approval-submit-state-propagation-contract-api` | submit succeeds against active seeded PD |
| Submit modal has no Next Approver input | `not-api-suitable` | — | modal shape is browser/UI only |
| Submit drives Quote `Status = Pending` | `covered` | `approval-submit-state-propagation-contract-api` | direct post-submit row assertion |
| Pending instance is readable | `covered` | `approval-instance-readback-contract-api` | proves record-instance readback contract |
| Matching approval step / workitem created | `covered` | `approval-submit-state-propagation-contract-api` | proves pending node + work item exist |
| Approval chain shows only matching steps | `partial` | `approval-submit-state-propagation-contract-api` | API proves seeded PD step/action graph and pending node; exact widget filtering is UI |
| Approver comments persist | `covered` | `quote-approval-approve-api`, `quote-approval-recall-success-api` | node/history comment persistence asserted |
| Approve advances and finalizes process | `covered` | `quote-approval-approve-api` | final `instanceStatus = Approved`, Quote `Status = Accepted` |
| Final approval clears pending state and enables Order path | `partial` | `quote-approval-approve-api`, order-create cases | backend final state is covered; banner/button rendering is UI |
| Recall resets Quote to Draft | `covered` | `quote-approval-recall-success-api` | direct Quote + ProcessInstance assertions |
| Recall history shows Removed/comment | `covered` | `quote-approval-recall-success-api` | node/history comment persistence asserted |
| Legacy/unsupported approval payload behavior | `covered` | `quote-approval-submit-api`, `quote-approval-recall-api` | keeps the current wire-shape guardrail explicit |

## Story `#173` Contract

| UAT point | API status | Watchdog case(s) | Note |
|---|---|---|---|
| Contract name format `XX-{RT}-XXXXXXXX` | `covered` | `contract-create-autonumber-contract-api`, `contract-lifecycle-formula-contract-api` | create-path and seeded-path both covered |
| Contract name mirrors business number | `covered` | `contract-lifecycle-formula-contract-api` | direct `Name == ContractNumber` assertion |
| Contract name is read-only | `not-api-suitable` | — | field edit affordance is UI/admin rendering |
| Status surface has valid lifecycle values | `covered` | `contract-status-describe-contract-api` | direct describe assertions for expected values |
| No `InApproval` / `Activated` in status picklist | `partial` | `contract-status-describe-contract-api` | runner lacks negative `not_contains`; expected values are proved, forbidden values are not explicitly asserted |
| Upload Archived Contr. quick action exists and is Approved-gated | `covered` | `contract-archived-upload-file-contract-api` | quick-action contract and transition intent proved |
| Upload button hidden on non-Approved statuses | `partial` | `contract-archived-upload-file-contract-api` | API proves quick-action gating expression, not page-action visibility rendering |
| Upload archived contract succeeds end-to-end | `partial` | `contract-archived-upload-file-contract-api` | action metadata/anchor surface covered; actual UI file-upload path not executed by API runner |
| After upload, Status auto-transitions to Effective | `partial` | `contract-archived-upload-file-contract-api` | transition target is proved in quick-action metadata, not executed via upload |
| End date / expiration date formula contract | `covered` | `contract-lifecycle-formula-contract-api` | seeded contract row asserts canonical end-date output |
| Contract patch/update surface works | `covered` | `contract-management-api`, `contract-status-transition-api` | update/readback contract preserved |

## Story `#172` Order

| UAT point | API status | Watchdog case(s) | Note |
|---|---|---|---|
| Positive create path from quote works | `covered` | `order-create-api`, `order-create-linkage-contract-api`, `order-from-quote-contract-api` | create succeeds and core linkages persist |
| Order name/number contract `XX-OF-YYYYMMDDNN` | `covered` | `order-create-api`, `order-create-field-inheritance-contract-api` | number format and `Name == OrderNumber` asserted |
| Order form pre-populates account/quote/opportunity/pricebook | `covered` | `order-create-linkage-contract-api`, `order-create-field-inheritance-contract-api` | API proves persisted inherited/linkage fields |
| Order inherits currency/payment fields from Quote | `covered` | `order-create-field-inheritance-contract-api` | `CurrencyIsoCode`, `Payment_Term__c`, `Payment_Type__c` asserted |
| Contract gate positive path | `covered` | `order-create-api` family | create succeeds with effective governing contract |
| Contract gate negative path | `covered` | `order-create-requires-effective-contract-api` | create is rejected without contract; now wired into scene |
| Upload Archived OF quick action exists and is Approved-gated | `covered` | `order-archived-form-file-contract-api` | quick-action contract and upload anchor surface proved |
| After archived OF upload, Status goes Activated | `partial` | `order-archived-form-file-contract-api` | runner proves metadata + persisted activated surface on seeded probe; not actual UI upload execution |
| QLI -> OI clone | `known-bug` | existing `order-item-linkage-contract-api` only covers seeded order-item anchors | do not claim UAT AC3 coverage; current product bug is `PACK-6` |
| OI preserves service dates/pricing from QLI | `blocked-by-product` | — | depends on clone path working first |
| Auto-Activated path with real cloned OIs | `blocked-by-product` | — | manual rollup already marks this as blocked by `PACK-6` |

## Net Result

### Newly added in this iteration

| Area | Case |
|---|---|
| `#773` readable refs / naming | `quote-line-item-readable-reference-contract-api` |
| `#771` positive final approval | `quote-approval-approve-api` |
| `#771` positive recall | `quote-approval-recall-success-api` |
| `#173` lifecycle row + end-date output | `contract-lifecycle-formula-contract-api` |
| `#173` status describe surface | `contract-status-describe-contract-api` |
| `#172` order field inheritance | `order-create-field-inheritance-contract-api` |
| `#172` negative contract gate integrated into scene | `order-create-requires-effective-contract-api` |

### Remaining non-closed areas

| Area | Reason |
|---|---|
| submit modal / pending banner / widget rendering / page button visibility | browser-only surface |
| actual file-picker upload UX for Contract / Order | browser/UI flow, not current API runner shape |
| explicit forbidden-status negative assert for Contract describe | runner currently has no `not_contains` assertion |
| `#172` AC3 / AC5 | product bug `PACK-6` still blocks truthful passing automation |
