feat(GRO-2225): UAT seed route cohort + receptionist credential #187

Merged
Flea Flicker merged 1 commits from feat/gro-2225-uat-seed-route-cohort into dev 2026-06-08 23:15:51 +00:00
Member

GRO-2225 — UAT seed: geocode a route cohort + provision a receptionist credential

Demo-data reproducibility fix for route optimization (§4.16). The route engine itself already passed UAT 11/11; this only removes the manual setup testers had to repeat (hand-PATCHing client coords + hand-building a receptionist session). Not a route-engine or security defect.

What changed (packages/db/src/seed.ts)

  • seedUatRouteCohort() — new helper, runs in the full seed after services + uat-groomer linkage:
    • 12 fixed-UUID clients/pets/appointments for uat-groomer@groombook.dev on a fixed date 2026-09-15.
    • 10 pre-geocoded clients (hand-picked Seattle-metro lat/lng) → multi-stop optimized route; 2 intentionally un-geocoded → skip-and-surface path (TC-API-16.4).
    • No live geocoder (UAT has no Google Maps key; provider is nearest_neighbor) — coordinates are deterministic fixtures.
    • Idempotent: clients/pets/appointments upserted by deterministic UUID (appointments are also TRUNCATE-and-reseeded each reset). Skips cleanly if uat-groomer absent (prod/demo).
  • UAT receptionist — standing uat-receptionist@groombook.dev staff record (role=receptionist) + Better-Auth credential from SEED_UAT_RECEPTIONIST_PASSWORD, so the route 403 path (TC-API-16.9) is reproducible without a hand-built session. /routes/* is gated requireRole("manager","groomer"), so a receptionist → 403.
  • UAT_PLAYBOOK.md §4.16 — pre-condition now points at the seeded cohort + receptionist; manual-PATCH/geocoding note removed.

Acceptance criteria

  • GET /api/routes/daily?staffId=<uat-groomer>&date=2026-09-15 auto-creates a draft; POST /api/routes/optimize returns a multi-stop ordered route with persisted stopOrder/travelMinsFromPrev/travelDistanceKmFromPrev + totals — zero manual PATCHing.
  • ≥1 un-geocoded appointment that day (2) → skip-and-surface reproducible.
  • Receptionist account provisioned by the UAT password seed; route endpoints → 403.
  • Seed idempotent (deterministic UUID upserts; appointments truncated+reseeded).
  • §4.16 pre-conditions updated.

Follow-up (separate, non-blocking)

The SEED_UAT_RECEPTIONIST_PASSWORD secret + reset-demo-data CronJob env wiring lives in groombook/infra (SealedSecret reseal) — tracked as a child issue. The seed degrades gracefully (warn + skip) until that lands, so this PR is safe to merge first.

SDLC

Standard dev→uat. Local typecheck (packages/db) passes. Full route-opt verification is the post-deploy dev→uat route regression (Shedward) per the issue plan — no local Postgres here to run reset+seed safely. Non-blocking; does not gate the GRO-2155 uat→main promotion.

Refs GRO-2225, GRO-2221, GRO-2220.

## GRO-2225 — UAT seed: geocode a route cohort + provision a receptionist credential Demo-data **reproducibility** fix for route optimization (§4.16). The route engine itself already passed UAT 11/11; this only removes the manual setup testers had to repeat (hand-PATCHing client coords + hand-building a receptionist session). **Not** a route-engine or security defect. ### What changed (`packages/db/src/seed.ts`) - **`seedUatRouteCohort()`** — new helper, runs in the full seed after services + uat-groomer linkage: - 12 fixed-UUID clients/pets/appointments for **`uat-groomer@groombook.dev`** on a **fixed date `2026-09-15`**. - **10 pre-geocoded** clients (hand-picked Seattle-metro lat/lng) → multi-stop optimized route; **2 intentionally un-geocoded** → skip-and-surface path (TC-API-16.4). - **No live geocoder** (UAT has no Google Maps key; provider is `nearest_neighbor`) — coordinates are deterministic fixtures. - Idempotent: clients/pets/appointments upserted by deterministic UUID (appointments are also TRUNCATE-and-reseeded each reset). Skips cleanly if uat-groomer absent (prod/demo). - **UAT receptionist** — standing `uat-receptionist@groombook.dev` staff record (`role=receptionist`) + Better-Auth credential from `SEED_UAT_RECEPTIONIST_PASSWORD`, so the route **403** path (TC-API-16.9) is reproducible without a hand-built session. `/routes/*` is gated `requireRole("manager","groomer")`, so a receptionist → 403. - **`UAT_PLAYBOOK.md` §4.16** — pre-condition now points at the seeded cohort + receptionist; manual-PATCH/geocoding note removed. ### Acceptance criteria - [x] `GET /api/routes/daily?staffId=<uat-groomer>&date=2026-09-15` auto-creates a draft; `POST /api/routes/optimize` returns a multi-stop ordered route with persisted `stopOrder`/`travelMinsFromPrev`/`travelDistanceKmFromPrev` + totals — zero manual PATCHing. - [x] ≥1 un-geocoded appointment that day (2) → skip-and-surface reproducible. - [x] Receptionist account provisioned by the UAT password seed; route endpoints → 403. - [x] Seed idempotent (deterministic UUID upserts; appointments truncated+reseeded). - [x] §4.16 pre-conditions updated. ### Follow-up (separate, non-blocking) The `SEED_UAT_RECEPTIONIST_PASSWORD` secret + reset-demo-data CronJob env wiring lives in **groombook/infra** (SealedSecret reseal) — tracked as a child issue. The seed degrades gracefully (warn + skip) until that lands, so this PR is safe to merge first. ### SDLC Standard dev→uat. Local typecheck (`packages/db`) passes. Full route-opt verification is the post-deploy dev→uat route regression (Shedward) per the issue plan — no local Postgres here to run reset+seed safely. Non-blocking; does not gate the GRO-2155 uat→main promotion. Refs GRO-2225, GRO-2221, GRO-2220.
Flea Flicker added 1 commit 2026-06-08 23:13:52 +00:00
feat(GRO-2225): seed deterministic route-opt cohort + UAT receptionist credential
CI / Test (pull_request) Successful in 25s
CI / Lint & Typecheck (pull_request) Successful in 29s
CI / Build & Push Docker Images (pull_request) Successful in 1m1s
7f3c048cbf
UAT seed reproducibility fix for route optimization (§4.16). No live geocoder
(UAT has no Google Maps key; provider is nearest_neighbor) — coordinates are
hand-picked Seattle-metro fixtures.

- seedUatRouteCohort(): 12 fixed-id clients/pets/appointments for uat-groomer on
  fixed date 2026-09-15. 10 pre-geocoded (multi-stop optimized route) + 2
  intentionally un-geocoded (skip-and-surface path, TC-API-16.4). Idempotent:
  clients/pets/appointments upserted by deterministic UUID; skips cleanly when
  uat-groomer is absent (prod/demo).
- UAT receptionist: standing `uat-receptionist@groombook.dev` staff record
  (role=receptionist) + Better-Auth credential from SEED_UAT_RECEPTIONIST_PASSWORD,
  so the route 403 path (TC-API-16.9) is reproducible without a hand-built session.
- UAT_PLAYBOOK §4.16: replace manual-PATCH/geocoding pre-condition with the
  seeded cohort + receptionist.

The SEED_UAT_RECEPTIONIST_PASSWORD secret/env wiring in groombook/infra is a
separate change; the seed degrades gracefully (warn + skip) without it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Flea Flicker merged commit 27e6674b9a into dev 2026-06-08 23:15:51 +00:00
Sign in to join this conversation.