Skip to content

V2 Launch Readiness Checklist

The explicit go/no-go list Stefan ticks off before flipping from V1 (XLSX + stringing.wagen.io) to V2 (RBO). One check per concern, each with an owner and a verification step. The final sign-off line at the bottom is Stefan's.

Audience: Stefan (operator + product owner). Engineers maintaining the items work back from this checklist when they pick up their slice.

Companion docs. This list is the operator-facing flip switch; the per-area mechanics live elsewhere:

The checklist is intentionally short. Each item is a single thing Stefan checks, not a sub-project. If an item starts to grow sub-bullets, it has graduated into its own design doc and the line here links there.

Data migration

  • [ ] V1 ETL run + reconciliation report reviewed. Owner: Vera.
  • Verification: Stefan ran python -m migration.etl --xlsx <his current XLSX> --reconcile --report-output /tmp/recon-prod.md against the prod connection per V1 upload spec, and the Summary line of the report is OK.
  • If FAIL, the Differences section names the gap. Investigate, fix V1 if appropriate, re-upload (the ETL is idempotent).

  • [ ] Per-year revenue tolerance confirmed. Owner: Vera.

  • Verification: in the same reconciliation report, every row of the per-year revenue table shows delta ≤ the displayed tolerance (default 0.01 CHF).

  • [ ] Counts match. Owner: Vera.

  • Verification: Counts section of the reconciliation report shows V1 vs V2 delta = 0 for both client orders and self orders. The 328-vs-329 V1-side artefact is documented and not a blocker (see V1 upload spec § The 328-vs-329 discrepancy).

  • [ ] Idempotency dry-run verified in test env. Owner: Vera.

  • Verification: Stefan ran the upload twice against the test DB; the second run's ETLStats shows skipped_idempotent > 0 and all-zero insert counters.

DE copy

  • [ ] Every UI string translated. Owner: Iris.
  • Verification: pybabel compile -d locales reports no fuzzy and no untranslated entries for de. msgfmt --statistics locales/de/LC_MESSAGES/messages.po shows 0 untranslated.
  • Stefan spot-checks the DE app locally (Stringer.default_locale = "de"): dashboard, Add-Stringjob, order detail, onboarding, and the magic-link invite copy all read as natural Swiss-German UI German, not machine translation.

  • [ ] DE PDF receipt template renders end-to-end. Owner: Iris (copy) + Pax-B (template wiring).

  • Verification: a test order whose client_profile.person.default_locale = "de" produces a receipt_de.html-rendered PDF whose totals, BYO suppression, and pricing block match the receipt-content spec. No EN strings leak through.

  • [ ] Locale resolution is correct. Owner: Iris + Pax (auth/middleware).

  • Verification: signed-in stringer with default_locale = "de" sees DE UI even when the browser sends Accept-Language: en. Unauthenticated landing page falls back to browser Accept-Language. Per the locked rule in i18n.md.

V1 listing redirect

  • [ ] Deprecation plan executed. Owner: Mira.
  • Verification: the redirect / freeze / banner cadence in docs/design/v1-listing-deprecation.md (Round 5 design — link forward) has run to completion. The public V1 listing at stringing.wagen.io either redirects to V2 or shows the agreed end-of-life notice; Stefan has stopped sharing V1 links.

  • [ ] No public exposure of client names remains on V1. Owner: Mira + Pax.

  • Verification: curl -sSL https://stringing.wagen.io/... returns the deprecation page (or a 301 to V2), not a listing of clients. Tracked end-state of #58 (M4 auth on the listing) confirmed.

Admin tooling

  • [ ] Catalogue moderation UI functional. Owner: Pax-A.
  • Verification: Stefan logs in as admin, opens the moderation queue, approves and rejects at least one promotion request each, sees the catalogue update accordingly. Per docs/design/admin-catalogue-moderation.md.

  • [ ] Reports rendering. Owner: Pax-B / Juno.

  • Verification: year/month rollups, top clients, and mean-turnaround report (#69 / M16) render against the migrated test DB and match the per-year totals from the reconciliation report.

  • [ ] Self-service export working. Owner: Juno.

  • Verification: Stefan triggers the per-stringer export (M20 / #73), receives the XLSX and full-context JSON, opens the XLSX in his usual tool, and the contents reconcile against the live order count.

  • [ ] DSAR portability + Person-merge admin tooling functional. Owner: Pax-C.

  • Verification: Stefan can run a DSAR export end-to-end against a test Person; the admin-dsar-queue.md and admin-person-merge.md design surfaces are reachable from the admin nav and operate as designed.

Smoke test in test env

  • [ ] Full happy path in test, end-to-end. Owner: Quill.
  • Verification: from a fresh signed-in stringer session, Stefan completes Add Stringjob → mark Strung → email receipt sends → mark Paid without leaving the V2 surface. The receipt arrives at the client's mailbox (test inbox), reads correctly in the client's locale, and the order detail page reflects all three lifecycle dates.
  • Run against the test DB after the dress-rehearsal upload (V1 upload spec step 2). One pass with an EN client, one pass with a DE client.

  • [ ] Self-job happy path. Owner: Quill.

  • Verification: same flow, but for a self-job (Stefan stringing his own racket). No receipt is emitted (per receipt-delivery rules); order shows in dashboard recent activity.

FADP

  • [ ] Consent capture wired. Owner: Iris (copy) + Pax-C (backend).
  • Verification: the consent gate per docs/requirements/fadp-implementation-asks.md is presented at the relevant moment (stringer onboarding, client first-receipt) and the captured consent record is persisted with timestamp + scope.

  • [ ] Retention policy in force. Owner: Pax-C.

  • Verification: the documented retention windows are configured (cron / scheduled job present and tested). At least one dry-run delete batch has executed against test data and produced the expected log output.

  • [ ] DSAR portability operational. Owner: Pax-C + Juno.

  • Verification: a test DSAR export request produces a machine-readable archive containing all data tied to the requesting Person within the documented SLA. The export format is the one named in the FADP asks doc; nothing extra leaks.

Auth

  • [ ] HS256 JWT verify working in test. Owner: Pax + Atlas.
  • Verification: gotrue v2.189.0 is the deployed auth provider, the shared secret is loaded from the keystone-managed env, and the V2 backend verifies session JWTs via HS256. Per project memory: gotrue is HS256, not RS256+JWKS. RS256+JWKS verify path explicitly NOT in the V2 launch surface.

  • [ ] No public exposure of customer data. Owner: Pax.

  • Verification: every route that returns client-PII is behind auth. A curl with no token gets 401 (or the unauthenticated landing page) on every order, listing, receipt, and report URL. Independently checked against the route table (#58 / M4 acceptance criteria).

  • [ ] Magic-link invite flow exercised end-to-end. Owner: Pax + Juno (UI half pending — see #74).

  • Verification: an invite is sent, the recipient opens it on a fresh device/browser, completes the password-set flow, and lands signed-in on their dashboard. UI polish for the post-invite state may still be in flight (#74 backend done, UI pending) — the launch gate is "happy path completes," not "every visual nit closed."

Backups

  • [ ] Postgres backups confirmed running. Owner: Atlas (keystone repo).
  • Verification: keystone's backup job is enabled for the prod RBO database; the most recent backup is younger than the documented RPO; a documented restore-test has been run within the last quarter and is on file in the keystone runbook.
  • This item lives in keystone, not racket-book — Atlas confirms via cross-link.

Final go-decision

When every box above is ticked, Stefan signs off:

Go decision. I, Stefan Wagen, confirm V2 is ready to receive production traffic and that V1 (XLSX-as-source + stringing.wagen.io) is officially deprecated as of the date below. Outstanding non-blockers (UI polish, cosmetic copy refinements) are tracked as follow-up issues and do not gate this flip.

Signed: ____ Date: ______

V2 launch URL: ____ Reconciliation report archived at: ____

After sign-off, the V2 launch is live. The reconciliation report becomes the audit trail of the migration and is archived per the data-migration RPO. Subsequent V1 spreadsheet edits by Stefan are no longer the source of truth; V2 is.