# Story Flow API Watchdog Plan

## Goal

This document defines the downstream API watchdog track that runs alongside the
existing browser watchdog track.

Hard goals:

1. support full run, single scene run, and single case run
2. use the same shared seed baseline as browser/manual testing
3. emit machine-readable case results for later agent triage
4. mark each scene as `ready`, `needs-data`, or `blocked`
5. keep scenario contracts story-anchored, not endpoint-anchored

## Scope Split

We keep two watchdog lanes:

1. `browser`
   - proves UX path, screenshots, operator-visible regressions
2. `api`
   - proves server contract, persistence, side effects, permission gates

The same story may require both lanes.

## Execution Contract

API watchdog must support:

1. all scenes
2. one scene only
3. one case only
4. serial or parallel scheduling per scene
5. shared baseline seed + scenario-local seed
6. final `report.json` + `report.md`

Minimum run selectors:

```bash
npm run watchdog-api -- --dry-run
npm run watchdog-api -- --scene lead
npm run watchdog-api -- --case lead-create-persist-api
```

## Case Model

Each API case still uses two files:

1. human file
   - `*.manual.md`
2. machine file
   - `*.api.yaml`

Machine file should declare only executable truth:

1. actor
2. auth flow
3. request steps
4. response assertions
5. persistence assertions
6. known blocker classification

## Data Layers

API scenes reuse the current seed layering:

1. `environment bootstrap`
2. `shared baseline seed`
3. `scenario-local seed`

Primary source docs:

1. `docs/story-test-data-plan.md`
2. `docs/story-test-data-catalog.md`
3. `watchdog/seeds/import-buckets.yaml`
4. `docs/api-watchdog-need-data-checklist.md`

## First-Wave Scene Matrix

| Scene | Primary Stories | API Value | Seed Need | Initial Status | Notes |
| --- | --- | --- | --- | --- | --- |
| `login-auth` | #780 | token/session/userinfo/revoke proof | `auth-identities` | `ready` | no browser dependency |
| `lead` | #757 #758 #759 #760 | create/search/convert persistence | `lead-core`, `account-contact-core`, `campaign-core`, `opportunity-core` | `ready` | best first scene family |
| `opportunity` | #744 #745 #747 #748 | OLI, amount rollup, stage/probability, activity | `opportunity-core`, `product-catalog`, `opportunity-line-items`, `activity-core` | `ready` | split by case dependency |
| `campaign` | #763 #764 #765 #766 | member create, status scoping, lookup search | `campaign-core`, `lead-core`, `account-contact-core` | `ready` | good API/browser mixed proof |
| `quote-approval-order-contract` | #771 #772 #773 #172 #173 | quote clone, approval submit, order/contract side effects | `quote-core`, `approval-core`, `order-core`, `contract-core` | `needs-data` | quote create/line-item inputs are now repo-tracked; approval/order/contract still trail |
| `security-and-visibility` | #730 #731 #732 | RLS/FLS/query/search/effective perms | `auth-identities`, `security-visibility`, shared business graph | `needs-data` | needs role/perm fixtures to be credible |
| `setup-admin-metadata` | #159 #166 #167 #717 | metadata/approval/flow admin APIs | `setup-metadata-samples` | `blocked` | mutation-heavy; not first wave |
| `reports-dashboards` | #171 | report save/share contracts | `reporting-core` | `blocked` | lower priority than sales path |
| `integration` | #170 | queue + sync contract | `integration-hubspot` | `blocked` | not first-wave watchdog target |

## First-Wave Case List

### P0

| Case ID | Story | Seed Buckets | Run Mode | Status | Known Pressure |
| --- | --- | --- | --- | --- | --- |
| `oauth-compatibility-api` | #780 | `auth-identities` | serial | `ready` | security-sensitive, but data-light |
| `lead-create-persist-api` | #758 | `lead-core` | serial | `ready` | low setup cost |
| `lead-convert-api` | #757 | `lead-core`, `account-contact-core`, `campaign-core`, `opportunity-core` | serial | `ready` | multi-object assertions |
| `opportunity-products-api` | #744 | `opportunity-core`, `product-catalog`, `opportunity-line-items` | serial | `ready` | requires stable pricebook graph |
| `opportunity-stage-progress-api` | #745 | `opportunity-core` | parallel-safe | `ready` | flow/date assertions can be isolated |
| `campaign-add-members-api` | #763 | `campaign-core`, `lead-core`, `account-contact-core` | parallel-safe | `ready` | good seed+write proof |
| `quote-create-api` | #772 | `opportunity-core`, `product-catalog`, `opportunity-line-items` | serial | `ready` | shared source opportunity/product graph is cataloged; no pre-seeded Quote is required |
| `approval-submit-api` | #160 | `approval-core`, `auth-identities` | serial | `needs-data` | process graph must exist |
| `security-effective-access-api` | #730 #732 | `auth-identities`, `security-visibility`, business graph | serial | `needs-data` | requires two contrasted users |
| `order-from-quote-api` | #172 | `quote-core`, `order-core`, `product-catalog` | serial | `blocked` | inherited capability gap |

### P1

| Case ID | Story | Seed Buckets | Run Mode | Status | Known Pressure |
| --- | --- | --- | --- | --- | --- |
| `contract-manage-api` | #173 | `contract-core`, `order-core`, `quote-core` | serial | `blocked` | inherited capability gap + upload path |
| `lead-status-progress-api` | #759 | `lead-core` | parallel-safe | `ready` | light persistence proof |
| `campaign-status-admin-api` | #764 | `campaign-core` | serial | `ready` | baseline campaign already carries mutable member-status fixtures |
| `opportunity-activity-api` | #748 | `activity-core`, `opportunity-core` | parallel-safe | `ready` | straightforward CRUD |

## Remote Issue Pressure

This is the current downstream execution view, not root-cause analysis.

| Scene | Status | Main Story / Issue Pressure |
| --- | --- | --- |
| `login-auth` | `medium` | #780 aggregates multiple security escape-hatch bugs; must treat as high-risk until API run passes |
| `lead` | `medium` | #757 and #758 both have many historical regressions, but upstream fix references exist |
| `opportunity` | `medium` | #744 and #745 have fix references, but rollup/flow assertions still need runtime proof |
| `campaign` | `medium` | #763 depends on lookup/search + scoped status behavior; seed realism matters |
| `quote-approval-order-contract` | `high` | #772 has upstream fix refs, but #160/#172/#173 still depend on heavier config or known capability gaps |
| `security-and-visibility` | `high` | #730/#732 need contrasted identities, sharing, FLS, and query/search proof in the same env |
| `setup-admin-metadata` | `high` | admin mutation path is broad and unstable for first-wave API automation |
| `reports-dashboards` | `high` | data + share model not yet staged |
| `integration` | `high` | not suitable before core sales path stabilizes |

## Per-Scene API Flow

### `login-auth`

1. password grant token
2. call `userinfo`
3. call protected endpoint
4. refresh token
5. revoke token
6. assert invalid-token response shape

### `lead`

1. create lead
2. query lead by email/name
3. assert compound/display fields
4. convert lead
5. assert account/contact/opportunity mapping
6. assert lead converted state

### `opportunity`

1. create or patch OLI
2. assert amount rollup
3. patch stage
4. assert probability + forecast side effects
5. create activity rows where needed

### `campaign`

1. query scoped campaign statuses
2. create campaign member against lead/contact
3. assert synthesized fields
4. patch member status

### `quote-approval-order-contract`

1. create quote from seeded opportunity
2. assert QLI clone
3. submit for approval
4. assert workitem/pending state
5. create order from quote
6. assert order item clone
7. assert contract linkage

## Data Planning Rules

Per scene:

1. prefer shared baseline for reusable graph
2. use scenario-local seed for mutation-heavy chains
3. seed relationships explicitly
4. do not rely on accidental production-synced tenant state

Required relationship baseline:

1. Lead -> CampaignMember
2. Account -> Contact
3. Account -> Opportunity
4. Opportunity -> OpportunityContactRole
5. Opportunity -> OpportunityLineItem
6. Quote -> QuoteLineItem
7. Quote -> Order
8. Order -> Contract

## Build Order

1. land API case contract + docs
2. land first executable scene: `lead`
3. land API runner skeleton with dry-run planning
4. land auth/lead/opportunity/campaign P0 execution
5. land quote/security cases
6. land approval/order/contract after data/config closure

## First Deliverable

Execution-ready first slice:

1. `lead-create-persist-api`
2. `lead-convert-api`
3. `oauth-compatibility-api`

Reason:

1. low seed ambiguity
2. direct backend value
3. fastest signal on shared env health

## Report Contract

Each API run report must include:

1. env health
2. auth success/failure
3. passed / failed / blocked case counts
4. failed request step
5. failed assertion
6. request/response artifact paths
7. seed bucket usage
8. linked story issue
9. blocker issue if known
