Skip to content
79%
Epic complete 1 pts since last snapshot
47 shipped23 done, unverified2 staged2 in review
M3 · BOUN-11293Tonyfieldwork-dashboard, fieldwork-processing

F3.3 — Dashboard Metrics

DoneHigh confidence

Deliver the data layer for the WPP fieldwork dashboard (F1.6): an hourly per-market metrics snapshot produced inside the fieldwork-processing Step Functions workflow (EventBridge hourly start → discover → fail-closed QC gate → per-market metrics compute → S3). Each successful cycle writes a validated, aggregate-only MetricsSnapshot JSON to a dedicated snapshot bucket: There is no HTTP API in v1 (design change 2026-08-05): the previously planned /v1/dashboard/* endpoints, ?fresh=true recompute, OpenAPI client codegen, and per-market SQS fan-out are all gone. The dashboard reads the snapshot JSON directly from S3; the embedded computedAt is the UI's "last sync" indicator. There is no per-request recompute path. v1 is scoped to data we already capture: completes vs target, starts/in-progress/IR%, screen-out breakdown, per-QC-check counts, research-defender counts, quota-cell fill, LOI (average/median/per-section), daily completes, grade/region tallies, and per-cell drill-down data. Derived values (percentages, deltas, totals) are deliberately not stored — consumers compute them. Forecast/RAG/Fount go-live metrics are v2, blocked on WPP supplying field dates.

19 of 28 stories shipped across 31 merged fieldwork-processing PRs: the hourly pipeline (discover to fail-closed QC gate to per-market metrics compute to S3 snapshot) is wired end to end, the 17 QC methods and workbook builders are ported, and a per-client API-key metrics endpoint shipped. Two export-scope stories are blocked on open product decisions and five more remain todo, including streaming export artifacts to S3 instead of buffering them in memory.

75%
Unchanged since last snapshot
Since last activity
5d
Oldest staged work
29d
Acceptance criteria covered
3/5
PRs open
0
Spec gap:Two stories are explicitly blocked on open product/design decisions (custom boolean labels in WPP demographics; how anonymous respondents appear in the usage export) rather than on engineering work.(BOUN-11585, BOUN-11586)
Spec gap:Export artifacts are still buffered in memory rather than streamed to S3, and the dashboard raw-responses export read path is unported; both remain todo.(BOUN-11587, BOUN-11634)

Release gate: main no release PR found— never assumed shipped.

Stories

28 tracked · 19 shipped, 2 done, unverified, 2 blocked, 5 to do

Acceptance criteria

  • The dashboard polls the snapshot and gets computedAt with no per-viewer Firestore fan-outBOUN-11442covered
  • A failed compute preserves the last-known-good snapshot, badges it stale with lastError/failedAttempts/lastSuccessfulAt, and a snapshot-age alarm fires after 3 missed cyclespartialBOUN-11442partially covered
  • A delayed or duplicate execution cannot overwrite a newer snapshot (ETag-conditional writes, monotonic computedAt guard)BOUN-11414covered
  • The snapshot validates against the strict, versioned MetricsSnapshotSchema and carries aggregates only, no PIIBOUN-11411covered
  • A QC failure anywhere fails the workflow closed, leaving the existing snapshot untouched and skipping metrics computepartialBOUN-11459partially covered

Gaps

Every acceptance criterion has at least partial evidence.

Criteria are read from the ticket description on every run. A gap closes on its own once a story or PR matching it appears — nothing here is closed by hand.