Commit Graph

38 Commits

Author SHA1 Message Date
Flea Flicker 5f01df819e fix(GRO-2299): redact googleMapsApiKey from PATCH /api/admin/settings response
CI / Test (pull_request) Successful in 24s
CI / Lint & Typecheck (pull_request) Successful in 27s
CI / Build & Push Docker Images (pull_request) Successful in 1m18s
The PATCH handler returned the full businessSettings row via .returning(),
echoing the encrypted googleMapsApiKey ciphertext back to the caller. Wrap the
return in the existing redactSettings() helper (after a !updated guard) so
redaction is applied symmetrically with the GET projection (GRO-2294).

- src/routes/settings.ts: guard + redactSettings(updated) on PATCH return
- src/__tests__/settings.test.ts: assert PATCH omits googleMapsApiKey
  (existing-row and auto-create-then-update branches)
- UAT_PLAYBOOK.md §13 TC-API-13.2: assert PATCH response omits the secret

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-09 06:50:20 +00:00
Flea Flicker fe412933ea GRO-2294: Route Optimization security hardening (geocode-batch limit cap + redact settings secret) (#193)
CI / Test (push) Successful in 27s
CI / Lint & Typecheck (push) Successful in 35s
CI / Build & Push Docker Images (push) Successful in 38s
2026-06-09 06:17:42 +00:00
Flea Flicker cd2f60e282 feat(GRO-2157): navigation export endpoints (Phase 2.3) (#190)
CI / Test (push) Successful in 24s
CI / Lint & Typecheck (push) Successful in 40s
CI / Build & Push Docker Images (push) Successful in 26s
2026-06-09 00:16:42 +00:00
Flea Flicker 27e6674b9a feat(GRO-2225): UAT seed route cohort + receptionist credential (#187)
CI / Test (push) Successful in 30s
CI / Lint & Typecheck (push) Successful in 32s
CI / Build & Push Docker Images (push) Successful in 45s
2026-06-08 23:15:51 +00:00
Flea Flicker aabedc8152 fix(GRO-2234): bounded sliding expiration for SSO portal sessions (#183)
CI / Test (push) Successful in 28s
CI / Lint & Typecheck (push) Successful in 29s
CI / Build & Push Docker Images (push) Successful in 38s
2026-06-08 18:55:43 +00:00
Flea Flicker ca62fb8ef6 feat(GRO-2156): travel buffer + reorder endpoint (Phase 2.2) (#180)
CI / Test (push) Successful in 27s
CI / Lint & Typecheck (push) Successful in 30s
CI / Lint & Typecheck (pull_request) Successful in 25s
CI / Test (pull_request) Successful in 24s
CI / Build & Push Docker Images (push) Successful in 43s
CI / Build & Push Docker Images (pull_request) Successful in 27s
2026-06-08 18:07:54 +00:00
Flea Flicker b842237425 fix(portal): GRO-2203 validate petId as UUID before PATCH lookup (500→404) (#177)
CI / Lint & Typecheck (push) Successful in 29s
CI / Test (push) Successful in 29s
CI / Lint & Typecheck (pull_request) Failing after 2s
CI / Test (pull_request) Successful in 25s
CI / Build & Push Docker Images (pull_request) Has been skipped
CI / Build & Push Docker Images (push) Successful in 47s
2026-06-08 17:03:44 +00:00
Flea Flicker d0c0b1b646 feat(GRO-2155): route CRUD + optimization endpoint (Phase 2.1) (#175)
CI / Test (push) Successful in 25s
CI / Lint & Typecheck (push) Successful in 28s
CI / Test (pull_request) Successful in 24s
CI / Build & Push Docker Images (push) Successful in 35s
CI / Lint & Typecheck (pull_request) Successful in 26s
CI / Build & Push Docker Images (pull_request) Successful in 25s
2026-06-08 13:57:07 +00:00
Flea Flicker 582c376df9 feat(GRO-2154): geocoding endpoints + auto-geocode on client mutations (#170)
CI / Test (push) Successful in 28s
CI / Test (pull_request) Successful in 23s
CI / Lint & Typecheck (pull_request) Successful in 26s
CI / Build & Push Docker Images (pull_request) Successful in 25s
CI / Lint & Typecheck (push) Failing after 14m33s
CI / Build & Push Docker Images (push) Has been skipped
2026-06-08 11:45:08 +00:00
Flea Flicker 6be78cae35 fix(portal): implement PATCH /portal/pets/:petId + enrich GET (GRO-2187) (#165)
CI / Test (push) Failing after 3s
CI / Lint & Typecheck (push) Successful in 16s
CI / Build & Push Docker Images (push) Has been skipped
CI / Test (pull_request) Successful in 12s
CI / Lint & Typecheck (pull_request) Successful in 15s
CI / Build & Push Docker Images (pull_request) Successful in 41s
2026-06-08 08:18:13 +00:00
Flea Flicker d1a68d93de fix(GRO-2123): serialize seed.ts with Postgres advisory lock
CI / Test (pull_request) Successful in 13s
CI / Lint & Typecheck (pull_request) Successful in 15s
CI / Build & Push Docker Images (pull_request) Successful in 58s
The reset-demo-data CronJob in groombook-uat intermittently failed with
FK 23503 on invoice_tip_splits because two pods could run the seed
concurrently: the new pod's TRUNCATE deleted rows the old pod was still
inserting.

Acquire a session-level advisory lock for the full duration of the seed.
CRITICAL: with postgres-js connection pooling, a pg_advisory_lock
acquired on one pooled connection and released on a different one is a
no-op (the lock is bound to the pg-backend that took it). We therefore
reserve a dedicated connection for the lock, take pg_advisory_lock(KEY)
on it, run the seed on the pooled connections, and release the lock +
reserved connection in a try/finally so a thrown seed error cannot leak
the lock or the connection.

Defence-in-depth with the infra PR that switches
concurrencyPolicy: Replace → Forbid on the reset-demo-data CronJob.

- Adds withSeedAdvisoryLock helper and runSeedBody extracted function
- Wraps seed() body in the helper; client.end() runs after the lock
  releases so a reserved connection is not returned to a closed pool
- SEED_ADVISORY_LOCK_KEY = 0x47524f4f ("GROO" in ASCII) — arbitrary
  stable 32-bit key, referenced in runbooks
- UAT_PLAYBOOK.md §3.29 documents the regression check

cc @cpfarhood

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-04 11:12:17 +00:00
Flea Flicker fc6c6ef752 fix(db): make services seed idempotent across resets (GRO-2064, GRO-2033 close-out) (#148)
CI / Test (push) Successful in 12s
CI / Lint & Typecheck (push) Successful in 15s
CI / Build & Push Docker Images (push) Successful in 28s
CI / Test (pull_request) Successful in 14s
CI / Lint & Typecheck (pull_request) Successful in 20s
CI / Build & Push Docker Images (pull_request) Successful in 39s
2026-06-02 04:54:33 +00:00
Flea Flicker 1f888ac716 security(audit): log owner-bypass reads in GET /pets/:id/profile-summary (GRO-2062)
CI / Test (pull_request) Successful in 12s
CI / Lint & Typecheck (pull_request) Successful in 15s
CI / Build & Push Docker Images (pull_request) Successful in 1m16s
Adds a defense-in-depth audit row to impersonationAuditLogs when the
staff-side owner-bypass path fires. Mirrors the failure-isolation
pattern in src/middleware/portalAudit.ts: insert failures are logged
and swallowed so a working read can never turn into a 500.

- New writeOwnerBypassAudit helper called only when isOwner === true.
- No DB migration; petId + actorStaffId go inside metadata jsonb.
- resolveImpersonationClientId stays pure (no audit side effects).
- Positive + negative tests + a cross-tenant regression test.
- UAT_PLAYBOOK.md §3.19d: TC-API-3.19d documents the audit assertion.

Parent tracking: GRO-2062 (Paperclip).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 04:10:58 +00:00
Flea Flicker 91eb2ccf71 fix(rbac): port Better-Auth user auto-provision into legacy ./src tree (GRO-2052) (#143)
CI / Test (push) Successful in 11s
CI / Lint & Typecheck (push) Successful in 15s
CI / Test (pull_request) Successful in 9s
CI / Lint & Typecheck (pull_request) Successful in 14s
CI / Build & Push Docker Images (push) Successful in 36s
CI / Build & Push Docker Images (pull_request) Successful in 26s
fix(rbac): port Better-Auth user auto-provision into legacy ./src tree (GRO-2052)

Ports the Better-Auth user-table auto-provision branch from canonical apps/api into the deployed ./src/middleware/rbac.ts so the owner-bypass in pets.ts is reachable for Better-Auth email/password customers. OIDC account branch retained as backward-compat fallback. Adds 5 rbac.test.ts cases and UAT_PLAYBOOK pre-condition docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Flea Flicker <flea@groombook.dev>
Co-committed-by: Flea Flicker <flea@groombook.dev>
2026-06-02 02:40:43 +00:00
The Dogfather 9903b51931 fix(pets): customer can view own pet profile summary (GRO-2013) (#135)
CI / Test (push) Successful in 16s
CI / Lint & Typecheck (push) Failing after 14m15s
CI / Build & Push Docker Images (push) Has been skipped
Adds an owner-bypass in the profile-summary handler for customers signed in via Better Auth, using the existing X-Impersonation-Session-Id portal session header. When a groomer-role staff row carries a valid impersonation session whose clientId matches the pet's clientId, skip groomerLinkageCheck and serve the summary. Otherwise fall through to the existing linkage check.

Resolves a 403 Forbidden where the customer (auto-provisioned by resolveStaffMiddleware as a 'groomer' staff row with no appointment linkage) could not read their own pet's profile.

Scope: GRO-2013 profile-summary endpoint only — no rbac.ts/schema/Dockerfile changes.

Tests: 6 new cases (owner-bypass, no-header, cross-tenant, expired, manager regression, linked-groomer regression); 294/294 pass.

UAT_PLAYBOOK.md: TC-API-3.19a/b/c.

Closes GRO-2013.

Co-authored-by: The Dogfather <20+gb_dogfather@noreply.git.farh.net>
Co-committed-by: The Dogfather <20+gb_dogfather@noreply.git.farh.net>
2026-06-01 18:40:25 +00:00
Flea Flicker fee62c895d fix(api): GRO-2014 — profile-summary 500 → 404/401/JSON-500 (#137)
CI / Lint & Typecheck (push) Successful in 16s
CI / Test (push) Successful in 16s
CI / Build & Push Docker Images (push) Successful in 46s
CI / Test (pull_request) Successful in 12s
CI / Lint & Typecheck (pull_request) Successful in 14s
CI / Build & Push Docker Images (pull_request) Failing after 18s
2026-06-01 18:16:29 +00:00
Flea Flicker 2251a172e3 docs(UAT_PLAYBOOK): document canonical source-of-truth for UAT seed passwords (GRO-2000) (#132)
CI / Lint & Typecheck (push) Failing after 5s
CI / Test (push) Successful in 12s
CI / Build & Push Docker Images (push) Has been skipped
CI / Test (pull_request) Successful in 11s
CI / Lint & Typecheck (pull_request) Successful in 19s
CI / Build & Push Docker Images (pull_request) Failing after 19s
2026-06-01 17:11:12 +00:00
Flea Flicker a9bac033fd docs(UAT_PLAYBOOK): add TC-API-3.28 for pet_size_category enum (GRO-1999) (#127)
CI / Test (push) Successful in 13s
CI / Lint & Typecheck (push) Successful in 15s
CI / Build & Push Docker Images (push) Successful in 36s
CI / Test (pull_request) Successful in 10s
CI / Lint & Typecheck (pull_request) Successful in 16s
CI / Build & Push Docker Images (pull_request) Successful in 37s
2026-06-01 13:50:16 +00:00
Flea Flicker 1faa7945c6 fix(seed): update credential password on re-run instead of skipping (GRO-1977) (#121)
CI / Lint & Typecheck (push) Failing after 2s
CI / Test (push) Successful in 12s
CI / Build & Push Docker Images (push) Has been skipped
fix(seed): update credential password on re-run instead of skipping (GRO-1977)
2026-06-01 00:23:53 +00:00
The Dogfather dd220598ca fix: add missing coat_type enum values (GRO-1971) (#118)
CI / Test (push) Successful in 18s
CI / Lint & Typecheck (push) Successful in 24s
CI / Build & Push Docker Images (push) Successful in 36s
2026-05-31 23:09:36 +00:00
Scrubs McBarkley bec7b014be fix(seed): remove stale uc.petName closure ref, correct medicalAlerts distribution to 30% (#115)
CI / Test (push) Successful in 11s
CI / Lint & Typecheck (push) Successful in 18s
CI / Build & Push Docker Images (push) Successful in 1m4s
CI / Test (pull_request) Successful in 12s
CI / Lint & Typecheck (pull_request) Successful in 14s
CI / Build & Push Docker Images (pull_request) Successful in 1m4s
2026-05-31 22:14:30 +00:00
Flea Flicker dff0e17a63 docs(UAT_PLAYBOOK): add TC-API-3.20 through TC-API-3.24 for seed data verification
CI / Lint & Typecheck (pull_request) Successful in 21s
CI / Test (pull_request) Successful in 35s
CI / Build & Push Docker Images (pull_request) Failing after 4m57s
Updated UAT_PLAYBOOK.md §4.3 — new seed data verification tests.

GRO-1898: After populating extended profile fields in the UAT seed, add
test cases to verify the data is actually present and shaped correctly.
Test cases cover:
- /api/clients returns seed data
- /api/pets/{id} returns all 5 extended fields for UAT test pets
- medicalAlerts shape is correct ({type, description, severity})
- Deterministic UAT pets (Charlie = behavioral alert, Delta = skin alert)
  are verifiably populated

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 01:15:55 +00:00
The Dogfather 7bdb92999a Merge pull request 'fix(gro-1866): add session-from-auth portal endpoint + role scope' (#93) from fix/gro-1866-sso-bridge into dev
CI / Test (push) Successful in 34s
CI / Lint & Typecheck (push) Successful in 38s
CI / Build & Push Docker Images (push) Failing after 1m46s
fix(gro-1866): add session-from-auth portal endpoint + role scope (#93)

Bridges Better Auth SSO sessions to portal sessions for real customers.
Adds role to genericOAuth scopes for Authentik role propagation.

Closes GRO-1866
2026-05-28 18:46:38 +00:00
Flea Flicker fa67b75b76 docs: add UAT test cases TC-API-8.8 through TC-API-8.11 for SSO bridge
Adds manual test cases covering:
- TC-API-8.8: valid Better Auth session → portal session (201)
- TC-API-8.9: no session → 401
- TC-API-8.10: no matching client → 404
- TC-API-8.11: returned sessionId works on subsequent portal calls

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-28 15:01:24 +00:00
The Dogfather 9622b109d0 Merge pull request 'feat(GRO-1177): add pet profile summary endpoint' (#30) from flea-flicker/pet-profile-summary into dev
CI / Lint & Typecheck (push) Successful in 12s
CI / Test (push) Successful in 12s
CI / Build & Push Docker Images (push) Successful in 2m52s
feat(GRO-1177): add pet profile summary endpoint (#30)

Adds GET /api/pets/:id/profile-summary with aggregated pet profile,
grooming history, visit count, and upcoming appointment.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-26 11:40:16 +00:00
Barcode Betty a25b2fe281 docs: add TC-API-3.18 and TC-API-3.19 to UAT_PLAYBOOK for visitCount regression + date filter
CI / Lint & Typecheck (pull_request) Successful in 12s
CI / Test (pull_request) Successful in 12s
CI / Build & Push Docker Images (pull_request) Successful in 1m4s
Updated UAT_PLAYBOOK.md §3.3 — new visitCount cap and past appointment filter test cases

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 11:34:25 +00:00
Scrubs McBarkley b61d899f81 fix(GRO-1757): auto-provision staff for OIDC users + UAT playbook updates (#83) 2026-05-25 23:39:57 +00:00
Flea Flicker 8c62ce2368 feat(GRO-1177): add GET /api/pets/:id/profile-summary endpoint
CI / Lint & Typecheck (pull_request) Successful in 9s
CI / Test (pull_request) Successful in 9s
CI / Build & Push Docker Images (pull_request) Successful in 37s
Returns aggregated pet profile with:
- All pet fields (basic + extended)
- recentGroomingHistory: last 10 entries from groomingVisitLogs with staff name join
- lastVisitDate: most recent groomedAt timestamp
- visitCount: count of completed appointments
- upcomingAppointment: next scheduled/confirmed appointment with service/staff name

Enforces same groomer RBAC as GET /:id. Returns 404 for non-existent pets.
Adds PetProfileSummary, GroomingHistoryEntry, and UpcomingAppointment types.
Adds unit tests covering: 404, 403, aggregated profile, empty history, no upcoming appt.
Updates UAT_PLAYBOOK.md §3 with TC-API-3.8 and TC-API-3.9.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 19:17:24 +00:00
Flea Flicker 7b2b533c16 docs(api): update UAT_PLAYBOOK.md §4.0 — new health endpoint path
CI / Test (pull_request) Successful in 9s
CI / Lint & Typecheck (pull_request) Successful in 10s
CI / Build & Push Docker Images (pull_request) Failing after 46s
Added TC-API-0.1 for GET /api/health (unauthenticated).
Corrected path from /health to /api/health (GRO-1544).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 13:49:15 +00:00
Flea Flicker d6f7ade7bd docs(UAT): add TC-API-1.16 for OIDC login Terraform-provisioned users
CI / Lint & Typecheck (pull_request) Failing after 6s
CI / Test (pull_request) Failing after 6s
CI / Build & Push Docker Image (pull_request) Has been skipped
Updated UAT_PLAYBOOK.md §4.1 — new TC-API-1.16 covering OIDC login
for Terraform-provisioned users (GRO-1509 fix, GRO-1511).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 22:44:04 +00:00
The Dogfather 6a3c1aa65e Merge pull request 'GRO-1178: client-facing enhanced pet profile editor' (#21) from flea-flicker/pet-profile-editor into dev
CI / Lint & Typecheck (push) Failing after 6s
CI / Test (push) Failing after 7s
CI / Build & Push Docker Image (push) Has been skipped
Merge PR #21: GRO-1178 — client-facing enhanced pet profile editor
2026-05-21 19:18:53 +00:00
Flea Flicker 609f86b927 fix(GRO-1461): expand UAT playbook with GRO-1272 auto-provision test cases
CI / Lint & Typecheck (pull_request) Failing after 6s
CI / Test (pull_request) Failing after 6s
CI / Build & Push Docker Image (pull_request) Has been skipped
Add TC-API-1.11 through TC-API-1.15 covering existing staff unaffected by
OIDC login, auto-provisioned role/superUser flags, and name fallback
variants (name present, no name+email present, no name+no email).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 16:37:43 +00:00
Chris Farhood 05cb91a13e fix(GRO-1365): address QA review findings on api/#21
1. Fix vi.mock factory: importOriginal -> db.and/eq/exists/or stubs
   (removes ReferenceError from undeclared imports in test)
2. Remove MedicalAlert.id — not in schema/migration/DB, only in types
3. Replace z.string().max(100) coatType with z.enum for CoatType union
4. Fix test expecting coatType "smooth" (invalid) -> "double" (valid)
5. Add TC-API-3.8 through TC-API-3.15 to UAT_PLAYBOOK.md §4.3

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 15:07:57 +00:00
The Dogfather 73461f2200 Merge pull request 'fix(GRO-1272): auto-provision staff record on first OIDC login' (#19) from fleaflicker/gro-1272-auto-provision-staff-dev into dev
CI / Lint & Typecheck (push) Failing after 7s
CI / Test (push) Failing after 7s
CI / Build & Push Docker Image (push) Has been skipped
fix(GRO-1272): auto-provision staff record on first OIDC login (#19)

Fixes HTTP 403 on all authenticated routes for new OIDC users by auto-creating
a minimal groomer staff record on first login when a Better-Auth user exists
but no staff record is found.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 14:16:42 +00:00
Flea Flicker 1345db3620 fix(GRO-1171): restore UAT_PLAYBOOK and add coatType/petSizeCategory to buildPet
Address QA review findings on PR #12:
- Add coatType and petSizeCategory to buildPet defaults in packages/db/src/factories.ts
  to fix TypeScript typecheck failure
- Restore UAT_PLAYBOOK.md (was deleted during monorepo extraction) and add
  §4.15 Buffer Rules test cases

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 10:01:39 +00:00
Chris Farhood 4a80440513 fix(GRO-1272): update rbac tests and UAT playbook for auto-provision
- Add user table mock and db.insert returning chain to rbac.test.ts
- Add three new tests: happy-path auto-provision, email-prefix fallback,
  and miss-path (no user → 403)
- Add TC-API-1.4 to UAT_PLAYBOOK.md §4.1 for first-login auto-provision

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:01:00 +00:00
Chris Farhood a0a75d7e25 feat(seed): provision Better-Auth email+password credentials for UAT accounts
Adds a seeding step after UAT staff creation that:
- Creates Better-Auth user records (emailVerified: true) for 4 UAT accounts
- Creates account records with providerId="credential" and scrypt-hashed passwords
- Links staff.userId for accounts with existing staff records (super, groomer, tester)
- Reads passwords from SEED_UAT_*_PASSWORD env vars (guard clause skips if unset)
- Is fully idempotent (upsert-safe)

Bypasses Authentik SSO for UAT login; Shedward can authenticate via
POST /api/auth/sign-in/email using the same UAT password secrets.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-20 01:17:54 +00:00
Chris Farhood 54a6b047fb docs: add UAT_PLAYBOOK.md for API service
Created comprehensive UAT playbook covering all 13 route groups with test cases for authentication, client management, pet management, appointment scheduling, services, staff management, invoicing & payments, customer portal, waitlist, search, reports, impersonation, and settings & setup.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-11 13:47:51 +00:00