Skip to content

Execution plan ​

Date: 2026-09-12. 17 analytics workstream boundaries, plus prerequisite PRs owned by existing MVP issues. Dependency sequencing split A02 delivery across projection #79, producer #82, reader #83, protected API #85, and historical-status PR #96; this remains one A02 acceptance boundary rather than one physical PR. #78/#79/#80/#82/#83/#85 are merged. A07 protected review analytics is in backend PR #95 (4a08fe3), stacked on #93; A02 historical status is in #96 (d113a4e), stacked on #95. Review-transition prerequisites #91/#92/#93 remain OPEN and are not on dev; #41/#42 remain incomplete.

Ownership and first action ​

The smart orchestrator owns A01 through merged backend #78 (f4ba2c3), A02 projection/reader/API through merged #79/#83/#85 and historical PR #96 (d113a4e), and A07 through merged pure projection #80 (216fd63) plus protected API PR #95 (4a08fe3). The #37 observation producer landed through #82 (5f7c88b). Frontend #31 and backend #86/#87 are landed. #88/#89/#90 merged only into a stale feature branch, so corrected dev-targeted #91/#92/#93 remain open; #95 is stacked on #93 and #96 on #95. Frontend A14 PR #33 depends on #95. #41/#42 remain incomplete pending the corrected merges and disposable database evidence.

One smart owner retains financial definitions, attribution, corrections, schema/migration review, query isolation/security, upstream contract acceptance, integration review, and final reconciliation. Lower-cost agents receive explicit files and frozen contracts for DTO wiring, fixture expansion, labels/states and documentation. Do not delegate financial policy to a mechanical implementer.

PR queue ​

IDs are stable ownership boundaries, not a requirement to serialize independent work. Every unit has a workstream document with acceptance, files, tests and RBAC TODOs. No unit is complete at this baseline.

ID / PRNarrow purpose and reason for boundaryDependenciesUnlocksStatus
A01Pure contracts and independently calculated reconciliation fixtures; establish one vocabulary before any read adapter.Existing rates onlyAll units / upstream interface agreementlanded — #78 / f4ba2c3
A02Bounded observation/performance reads and creator/admin chart API; one time/filter contract removes divergent historical inference.A01, #37 observation reader and #41/#42 reliable status events for historical filtersA10/A11/A13#79/#82/#83/#85 landed; #96 (d113a4e) historical slice active on #95; exact per-submission unknown rules frozen; no current-accepted query in historical mode; database evidence blocked
A03Shared exact funding/earning/hold/allocation read projections and legacy coverage adapter; no routes or writers.A01; #31/#33/#37/#53/#54/#55/#56/#59 source interfaces; #58 completion/release contractA04/A05/A06/A09/A10blocked
A04Creator summary/campaign/submission/leaderboard/balance reads under one ownership contract. No payout request or eligibility mutation.A03; payout owner supplies eligibilityA11/A12blocked
A05Paginated attributable own payout history; operation versus allocation and timestamp contract merits separate review.A03; #56–#59 read modelsA12blocked
A06Staff/campaign financial APIs and compatibility consumers; fixes CPM/RPM mismatch without exposing new public data.A03; A02 for posted/observed time series compositionA11/A13blocked
A07Review event aggregates and bounded contextual reads; separate actor/accountability privacy and upstream coverage.A01; #41/#42/#68 reliable normalized event reader; #43 when reusing queue sortingA14PR #95 / 4a08fe3 in progress, stacked on #93; protected route and tests ready; #41/#42/#68 and database evidence remain open
A08Durable risk/hold aggregates; unique held liability versus multiple signals needs its own review.A01/A03; #55/#59A15blocked
A09Campaign-relative historical group/member cohorts; prevent overlap double counting.A02/A03; #26/#27/#37/#41, #76 for real fixture setupA16blocked
A10Reuse shared performance/paid-gross readers inside delivered report; privacy and revocation regression are the boundary.A02/A03; A06 contract agreedA17blocked
A11Creator overview/campaign displays, precise RPM labels and observed charts; backend defines money. Own shared money/coverage formatter.A02/A04/A06A12/A13 formatter reuse; A17blocked
A12Creator submission and payout history, full-filter summaries and statuses; one history UX boundary.A04/A05; A11 shared formattersA17blocked
A13Staff overview/campaign finance and performance, bounded server filters/sorts.A02/A06; A11 shared formattersA17blocked
A14Review activity and contextual decisions within review screens; separate from risk and money UI. Committed-event summaries remain separate from queue state; UTC exclusive-to/campaign/status filters, aggregate/day buckets, lazy history, stable asOf pagination, explicit coverage/actor labels, full reasons and post-moderation invalidation are implemented.A07 backend #95 (4a08fe3) stacked on #93; #68 reviewer-accountability coverageA17 after review and DB/manual/browser evidencePR #33 / 97f7662 open, clean, mergeable; feature/review-analytics-ui → frontend dev
A15Hold/risk and unresolved payout summaries; read-only integration, not fraud decision workflow.A08; A11 shared formattersA17blocked
A16Group/member period metrics and archive reporting; explicit cohort/union presentation.A09; A11 shared formattersA17blocked
A17Cross-view regression, migration/cutover evidence and manual fixture acceptance; focused integration tests, no feature bundle.A02–A16 and release-relevant upstream gates#51/#52/#63 acceptance reviewblocked

Waves and parallel work ​

  1. Contract wave: A01. In parallel the owner coordinates the minimum prerequisite interfaces listed in readiness; no analytics implementation of those domains. #76, #36/#37, #31–#33, #26/#27 and #41/#43 can progress under their separate owners after migration/file coordination.
  2. Performance/review wave: A02's pure projection, producer, normalized reader and protected API landed in #79/#82/#83/#85; PR #96 (d113a4e) is the historical-status slice stacked on #95. Its per-submission history is ordered by occurredAt, recordedAt, eventId; no prior event means unknown, and malformed, campaign-conflicting, or discontinuous history makes the affected submission unknown. Historical mode does not query current accepted state. A07 protected review analytics is in #95 (4a08fe3), stacked on #93, using bounded canonical event reads, v1/v2 normalization, partial diagnostics, aggregate-before-pagination, and recorded-time ordering. Validation for #96 passed 11 analytics/routes suites, creator-route checks, build, and diff check; no migration/RBAC map changed. Carry-forward PRs #91/#92/#93 remain OPEN and are not on dev; #41/#42 remain incomplete, #68 accountability coverage remains a blocker, and disposable loopback _test database evidence is still required. Do not claim either A02 or A07 complete from branch tests alone.
  3. Financial source wave: funding/history/rate inputs → #53/#54 accounting → #55 hold integration → #56/#59 reservation/operation records → #57/#58 completion/reconciliation. Exact ordering of schema/hold interface work can overlap, but one smart integrator owns writer invariants. A03 lands only against accepted source contracts, with unavailable/legacy coverage supported. Production paid claims still need real provider evidence.
  4. API wave: A04, A05 and A06 may be developed in parallel on dedicated service/route modules once A03 is stable. Because A04/A05 touch payouts.ts, merge their router mount hunks sequentially. A08/A09/A10 may then proceed independently in risk/group/report domains. A10 does not rebuild sponsor access.
  5. Audience wave: A11 establishes shared presentation primitives. A12/A13/A15/A16 can then run in parallel in distinct feature/surface folders as their APIs land; A14 remains independent. Keep RBAC navigation decisions with that owner. Do not widen staff paths merely to make a screen reachable.
  6. Integration wave: A17 compares equal scopes and validates all release gates. Resolve actual regressions in their owning PR/unit, not as unrelated cleanup in the test PR.

If an upstream owner is absent, record the exact missing contract and continue ready independent work. Do not mark an analytics unit ready because an upstream parent is open or closed; require its exported facts/tests. Conversely, the separate RBAC project never blocks pure analytics contracts/read-query development under preserved guards.

File and migration conflict ownership ​

Shared areaOwner / rule
prisma/schema.prisma, migration ordering and financial writersUpstream domain owner with one smart integration reviewer. Analytics creates no ledger migration. Rebase and regenerate candidate migrations sequentially; no concurrent schema ownership.
src/utils/analytics/ (proposed)A01 definitions, A02 performance reader, A03 financial reader. Domain files distinct; one reviewer approves shared types.
src/api/routes/admin.ts / composition rootA06 owns finance adapter replacements; A02/A07 use dedicated route/service modules and coordinate narrow mounts. Avoid two agents editing the monolith simultaneously.
payouts.ts / adminPayoutReview.tsPayout owner owns mutations/state machine. A04/A05 only additive GET adapters, with explicit hunk ownership. No changes to /request, approve/send/retry.
viewSnapshots.ts / tracking reconciliationA02 reads; #37 owns writes. Keep legacy wrappers until consumers migrate. No analytics job-application changes.
features/analytics/ or existing shared formattersA11 owns the narrow exact-money/coverage helper; A12/A13/A15/A16 consume it. Do not create a design-system refactor.
RBAC helpers, action policy, dashboard access allowlistSeparate RBAC owner only. Analytics adds specific TODOs/tests preserving current guards.
Sponsor domainA10 owns reader reuse; existing grant/token implementation stays intact.

PR and rollout requirements ​

Each PR references its leaf issue using Refs #… (cross-repository full URL when needed), names this unit, declares stacked dependencies and later units unlocked, and records focused tests. Do not use an automatic closing keyword on an incomplete leaf. Use Conventional Commit subjects; add a concise motivation/behavior body when useful. No unrelated cleanup.

Additive API contract changes land before their frontend consumers. New decimal strings never replace old numeric fields in place. A backend failure/unknown source remains explicit, not a synthetic zero. Old clients continue using old fields until switched; release notes identify their legacy estimate limitations. Retire old fields only after consumer audit and a separate explicit follow-up, not as hidden scope in A17.

All schema/backfill work must satisfy migration and cutover gates before scheduling. A release can retain old financial reads while new projections run in shadow; do not enable another financial writer or duplicate dispatch. Rolling back a reader is not authorization to roll back economic facts.

For the review-transition stack, deploy frontend #31 before backend #87 so older backends continue receiving compatible command fields. Rollback retains v2 AuditEvent facts and reverts the reader/writer behavior; #86/#87 introduce no migration.

Merge topology correction (2026-09-12): backend dev is d937bfe with #86/#87 landed, and frontend dev is e4b5f5c with #31 landed. #88/#89/#90 merged only into stale feature/review-transition-command and are absent from dev. Dev-targeted carry-forward PRs #91 (eaee854, scraper), #92 (9f38877, payout), and #93 (151a80f, history) are open. A07 PR #95 is stacked on #93; A02 historical status PR #96 is stacked on #95; frontend A14 PR #33 depends on #95. Run disposable PostgreSQL transition/history-ordering evidence after the corrected stack lands; no TEST_DATABASE_URL exists, configured databases are remote/non-test, and local PostgreSQL is down. #41/#42 remain incomplete.