Commit Graph

283 Commits

Author SHA1 Message Date
Flea Flicker 61f23e47f1 docs(GRO-2359): add UAT_PLAYBOOK §4.20 clients-from-auth test cases
CI / Lint & Typecheck (pull_request) Successful in 19s
CI / Test (pull_request) Successful in 21s
CI / Build & Push Docker Images (pull_request) Successful in 1m9s
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-05 09:20:03 +00:00
Flea Flicker ab5f08e4c0 fix(GRO-2652): restore ci.yml from double-base64 corruption; fix outpuds typo
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-05 09:19:55 +00:00
gb_flea 5accf73363 ci: trigger CI for dev branch (PR-223 dev→uat) 2026-08-05 09:04:17 +00:00
Flea Flicker 299a157561 fix(GRO-2652): boot ECONNRESET resilience — retry-with-backoff in initAuth, server-first startup
Merges feature/GRO-2652-boot-econnreset-resilience into dev. CI passed (run #440). Fixes PROD CrashLoopBackOff caused by bare top-level await initAuth() + unhandled ECONNRESET in auth_provider_config DB query.
2026-08-05 09:01:12 +00:00
gb_flea af1af5c211 ci: trigger CI run for ignore-error=true cache-to fix 2026-08-05 08:56:30 +00:00
Flea Flicker 713e8bf415 ci: add ignore-error=true to all cache-to targets
Gitea OCI registry sporadically rejects cache blob writes with
"error writing layer blob: unknown" — this fails the build step
even though the image itself was pushed successfully. Adding
ignore-error=true makes cache write failures non-fatal so the
build proceeds regardless of registry-side cache issues.

Fixes recurring CI failure on Build and push Seed image step.
2026-08-05 08:54:00 +00:00
Flea Flicker 8d42bfffc9 test(GRO-2652): add boot resilience UAT test cases (TC-API-19.x)
CI / Test (pull_request) Successful in 25s
CI / Lint & Typecheck (pull_request) Successful in 28s
CI / Build & Push Docker Images (pull_request) Successful in 56s
New section 4.19 verifies:
- /health available before initAuth completes
- auth routes return 503 (not crash) during init retry window
- pod restart count stays stable after deploy
- retry log lines emitted correctly
- auth recovers after transient DB hiccup

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-05 08:22:00 +00:00
Flea Flicker 095efb1cca fix(GRO-2652): start server before initAuth; retry auth init on ECONNRESET
Previously: await initAuth() was a top-level ESM await. Any boot-time
ECONNRESET from Postgres propagated as an uncaught module-evaluation
error and killed the process before the server even started.

Now:
- serve() starts immediately so /health and public routes are available
- initAuth() runs in a retry loop (up to 10 attempts, exponential
  500 ms → 30 s); a permanent failure degrades to 503 on auth routes
  (existing catch-to-503 in authRouter) rather than crashing the pod

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-05 08:21:14 +00:00
Flea Flicker 632dadd064 fix(GRO-2652): retry DB query in initAuth on transient ECONNRESET
The auth_provider_config DB query at boot has no error handling;
a transient ECONNRESET causes authInitPromise to reject, propagating
to the top-level await initAuth() and crashing the process (exit 1).

Add up to 5 retry attempts with exponential backoff (1 s, 2 s, 4 s, 8 s)
so a single connection reset does not abort initialization.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-05 08:17:31 +00:00
Flea Flicker dace2c4e66 fix(GRO-2586): enforce trusted-origins allowlist on Better Auth CORS responses (#219)
CI / Lint & Typecheck (push) Successful in 19s
CI / Test (push) Successful in 21s
CI / Build & Push Docker Images (push) Successful in 1m4s
fix(GRO-2586): enforce trusted-origins allowlist on Better Auth CORS responses

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-26 13:35:59 +00:00
Flea Flicker c01e4acf0a feat(GRO-2425): split CORS_ORIGIN on commas for multiple trusted auth origins (#216)
CI / Test (push) Successful in 30s
CI / Lint & Typecheck (push) Successful in 45s
CI / Build & Push Docker Images (push) Successful in 1m10s
CI / Test (pull_request) Successful in 25s
CI / Lint & Typecheck (pull_request) Failing after 12m18s
CI / Build & Push Docker Images (pull_request) Has been skipped
feat(GRO-2425): split CORS_ORIGIN on commas for multiple trusted auth origins

Co-authored-by: Flea Flicker <flea@groombook.dev>
Co-committed-by: Flea Flicker <flea@groombook.dev>
2026-06-18 00:46:29 +00:00
Flea Flicker 10b78d810d Merge pull request 'feat(GRO-2359): add POST /api/portal/clients-from-auth for OOBE' (#212) from feature/2357-p2-portal-clients-from-auth into dev
CI / Test (push) Successful in 26s
CI / Lint & Typecheck (push) Successful in 32s
CI / Build & Push Docker Images (push) Successful in 41s
GRO-2359 (api): feat(GRO-2359): add POST /api/portal/clients-from-auth for OOBE (#212)
2026-06-11 16:34:34 +00:00
Flea Flicker cdeebec021 feat(GRO-2359): add POST /api/portal/clients-from-auth for OOBE (web)
CI / Test (pull_request) Successful in 29s
CI / Lint & Typecheck (pull_request) Successful in 41s
CI / Build & Push Docker Images (pull_request) Successful in 1m40s
The OOBE flow on the web portal calls this endpoint to create a fresh
`clients` row bound to the Better Auth user's email when the SSO
bridge returns 404. Returns 201 on success, 409 if a client with that
email already exists (portal-selection case), 401/503 on auth issues,
400 on invalid body.

The OOBE success path navigates the user back to `/` and lets the
existing `session-from-auth` re-bridge; the new client is now
resolvable by email, so the bridge mints a real portal session.

Tests cover: 401 (no session), 400 (zod), 201 + persisted values
(name trimmed, optional fields normalized to null), 409 (existing
client or unique-constraint race), 503 (auth not configured).

Paired with the web PR on `feature/2357-p2-sso-to-oobe-routing`.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-11 16:17:16 +00:00
Flea Flicker 1d6b906202 Merge pull request 'fix(GRO-2342): portal waitlist card populates service {id, name}' (#208) from feat/GRO-2342-portal-waitlist-servicename into dev
CI / Test (push) Successful in 28s
CI / Lint & Typecheck (push) Successful in 29s
CI / Build & Push Docker Images (push) Successful in 33s
2026-06-10 09:13:55 +00:00
Flea Flicker 277f459237 fix(GRO-2342): portal waitlist card populates service {id, name}
CI / Test (pull_request) Successful in 26s
CI / Lint & Typecheck (pull_request) Successful in 29s
CI / Build & Push Docker Images (pull_request) Successful in 1m15s
Cosmetic follow-up to GRO-2319 (Phase 4 review by CTO). The synthetic
waitlist card on GET /portal/appointments returned service: {id} only,
so the portal fell back to the literal 'Service' label. CMPO spec did
not call for a service name on the waitlist card, but populating the
real name is non-urgent and closes the cosmetic gap.

- src/routes/portal.ts: include a services SELECT (in addition to
  pets and staff) covering both appointment and waitlist serviceIds.
  serviceMap feeds a service.name lookup. The synthetic waitlist
  card's service object is now {id, name} — same shape the
  appointments join returns — so the portal renders the real name.
  The appointments join also gains a name (consistent shape, no
  regression for the existing path).
- src/__tests__/portal.test.ts: mock the services table and assert
  service: {id, name} on both the synthetic waitlist card and the
  appointment card.
- UAT_PLAYBOOK.md: TC-API-8.20 covering the waitlist card service
  name (TC-API-8.19 retained verbatim for the original GRO-2319
  surfacing contract).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-10 09:11:08 +00:00
Flea Flicker ef18ed7376 feat(GRO-2319): surface active waitlist entries on portal appointments + seed (#204)
CI / Test (push) Successful in 28s
CI / Lint & Typecheck (push) Successful in 33s
CI / Build & Push Docker Images (push) Successful in 45s
2026-06-09 10:41:08 +00:00
Flea Flicker d61607f4c5 feat(seed): seed upcoming appointments across statuses for UAT portal customer (GRO-2311) (#201)
CI / Test (push) Successful in 31s
CI / Lint & Typecheck (push) Successful in 2m35s
CI / Build & Push Docker Images (push) Successful in 1m25s
2026-06-09 09:53:04 +00:00
Flea Flicker 2853ce73a5 GRO-2172: add missing extended pet fields to create/update schemas (#199)
CI / Lint & Typecheck (push) Successful in 1m13s
CI / Test (push) Successful in 2m31s
CI / Build & Push Docker Images (push) Successful in 35s
2026-06-09 08:56:22 +00:00
Flea Flicker 1e0747324d fix(GRO-2139): serialize reset→migrate→seed under the seed advisory lock (#160)
CI / Test (push) Successful in 24s
CI / Lint & Typecheck (push) Successful in 37s
CI / Build & Push Docker Images (push) Successful in 36s
Serialize the entire db:reset chain (DROP → migrate → seed) inside one withSeedAdvisoryLock callback so a concurrent same-PRNG seeder cannot interleave and collide on invoices_pkey. Pool sized max:6 (1 reserved for the lock + work headroom) to avoid the connection-starvation deadlock the CTO caught. Verified with three end-to-end live db:reset runs against a throwaway Postgres.

cc @cpfarhood
2026-06-09 08:44:58 +00:00
Flea Flicker b4b48f7b50 fix(GRO-2299): redact googleMapsApiKey from PATCH /api/admin/settings response (#195)
CI / Test (push) Successful in 26s
CI / Lint & Typecheck (push) Successful in 30s
CI / Build & Push Docker Images (push) Successful in 38s
2026-06-09 06:52:48 +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 6702086c7b fix(GRO-2235): return 409 on duplicate portal waitlist submit (#189)
CI / Test (push) Failing after 14m19s
CI / Lint & Typecheck (push) Failing after 14m19s
CI / Build & Push Docker Images (push) Has been skipped
2026-06-08 23:50:21 +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 29c42e3130 fix(portal): validate waitlist preferredTime/preferredDate, return 400 on bad input (GRO-2211) (#179)
CI / Test (pull_request) Successful in 26s
CI / Test (push) Successful in 29s
CI / Lint & Typecheck (pull_request) Successful in 31s
CI / Lint & Typecheck (push) Successful in 34s
CI / Build & Push Docker Images (pull_request) Failing after 13s
CI / Build & Push Docker Images (push) Successful in 48s
2026-06-08 17:19:39 +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 b9fc688769 fix(db): wait for/retry DB DNS resolution before drizzle-kit migrate (GRO-2163) (#161)
CI / Test (push) Successful in 28s
CI / Lint & Typecheck (push) Successful in 31s
CI / Build & Push Docker Images (push) Successful in 47s
2026-06-08 13:37:30 +00:00
Flea Flicker 14d7889ec0 fix(portal): drop writable photoKey from PATCH /portal/pets — S3 key-hijack (GRO-2187/GRO-2198) (#172)
CI / Test (push) Successful in 24s
CI / Lint & Typecheck (push) Successful in 26s
CI / Build & Push Docker Images (push) Successful in 29s
CI / Lint & Typecheck (pull_request) Successful in 24s
CI / Test (pull_request) Successful in 30s
CI / Build & Push Docker Images (pull_request) Successful in 44s
2026-06-08 12:39:02 +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 eec198a661 fix(ci): GRO-2197 api lint/typecheck/test run root scripts (de-false-green) (#169)
CI / Test (push) Successful in 25s
CI / Lint & Typecheck (push) Successful in 30s
CI / Build & Push Docker Images (push) Successful in 3m23s
2026-06-08 11:09:33 +00:00
Flea Flicker 04b235c861 Merge pull request 'feat(GRO-2153): abstracted geocoding service (Nominatim + Google)' (#167) from feat/gro-2153-geocoding-service-dev into dev
CI / Test (push) Failing after 13m50s
CI / Lint & Typecheck (push) Failing after 13m50s
CI / Build & Push Docker Images (push) Has been skipped
CI / Test (pull_request) Successful in 11s
CI / Lint & Typecheck (pull_request) Successful in 16s
CI / Build & Push Docker Images (pull_request) Successful in 3m45s
2026-06-08 09:40:52 +00:00
Flea Flicker 21fb1b30d2 ci: retrigger build (registry layer-pull hang on prior run)
CI / Test (pull_request) Failing after 14m1s
CI / Lint & Typecheck (pull_request) Failing after 14m1s
CI / Build & Push Docker Images (pull_request) Has been skipped
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-08 09:40:42 +00:00
Flea Flicker 2fa6e3d87b feat(GRO-2153): abstracted geocoding service (Nominatim + Google)
CI / Test (pull_request) Successful in 13s
CI / Lint & Typecheck (pull_request) Successful in 20s
CI / Build & Push Docker Images (pull_request) Failing after 27m22s
Phase 1.2 of Route Optimization. Adds a provider-agnostic geocoding
service layer in the deployed src/ tree:

- GeocodingProvider interface + GeocodeResult type
- NominatimGeocodingProvider (default, free, self-hostable) with an
  internal rate limiter enforcing the 1 req/sec Nominatim usage policy
- GoogleGeocodingProvider (optional fallback) keyed by the encrypted
  businessSettings.googleMapsApiKey (decrypted via decryptSecret) or
  GOOGLE_MAPS_API_KEY env fallback
- resolveGeocodingProvider() selecting on businessSettings.routeOptimizationProvider,
  with safe fallback to Nominatim when google is configured but no usable key
- geocodeBatch() throttled batch utility (honors provider rate limit,
  captures per-item errors, optional progress callback)
- 20 unit tests covering both providers, selection, throttle spacing, and batch

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-08 09:01:36 +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 40bd6dcfea Merge pull request 'feat(GRO-2152): route optimization schema migration' (#164) from feat/gro-2152-route-optimization-schema-dev into dev
CI / Test (push) Failing after 4s
CI / Lint & Typecheck (push) Successful in 15s
CI / Build & Push Docker Images (push) Has been skipped
2026-06-08 07:55:35 +00:00
Flea Flicker 4884961c8e feat(GRO-2152): route optimization schema migration
CI / Test (pull_request) Successful in 53s
CI / Lint & Typecheck (pull_request) Successful in 1m0s
CI / Build & Push Docker Images (pull_request) Successful in 4m13s
Add the database foundation for mobile groomer route optimization:

- clients: latitude/longitude (double precision) + geocodedAt
- groomer_routes: per-(staff, date) route with route_status enum,
  totals, optimizedAt; UNIQUE(staff_id, route_date)
- route_stops: ordered stops FK->groomer_routes (cascade) + appointments,
  lat/lng, per-leg travel mins/distance, bufferMins;
  UNIQUE(route_id, appointment_id) and UNIQUE(route_id, stop_order)
- business_settings: defaultTravelBufferMins (default 15),
  routeOptimizationProvider (default nominatim), googleMapsApiKey
  (encrypted at rest at the app layer)
- Idempotent hand-authored migration 0041 + journal entry (when=max+1)

Lands in packages/db (the deployed schema/migration source per the
Dockerfile migrate stage); apps/api is the legacy CI-only copy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:48:10 +00:00
Flea Flicker 93be4d8f72 chore: delete stale apps/api/src/db/seed.ts duplicate (GRO-2129) (#158)
CI / Test (push) Successful in 15s
CI / Lint & Typecheck (push) Successful in 18s
CI / Build & Push Docker Images (push) Successful in 38s
chore: delete stale apps/api/src/db/seed.ts duplicate (GRO-2129) (#158)
2026-06-04 12:44:46 +00:00
Flea Flicker f67b96ddfe Merge pull request 'fix(GRO-2123): serialize seed.ts with Postgres advisory lock' (#155) from flea-flicker/gro-2123-seed-advisory-lock into dev
CI / Test (push) Successful in 11s
CI / Lint & Typecheck (push) Successful in 16s
CI / Build & Push Docker Images (push) Successful in 25s
CI / Test (pull_request) Successful in 10s
CI / Lint & Typecheck (pull_request) Successful in 16s
CI / Build & Push Docker Images (pull_request) Successful in 28s
2026-06-04 11:23:41 +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 e9f94a2bd7 fix(seed): GRO-2100 run uat-groomer linkage AFTER services seed (regression in #151) (#153)
CI / Test (push) Successful in 12s
CI / Test (pull_request) Successful in 12s
CI / Lint & Typecheck (pull_request) Successful in 15s
CI / Build & Push Docker Images (pull_request) Successful in 29s
CI / Lint & Typecheck (push) Failing after 12m57s
CI / Build & Push Docker Images (push) Has been skipped
fix(seed): GRO-2100 run uat-groomer linkage after services seed (#153)

Co-authored-by: Flea Flicker <flea@groombook.dev>
Co-committed-by: Flea Flicker <flea@groombook.dev>
2026-06-02 20:11:45 +00:00
Flea Flicker de16c50040 fix(seed): GRO-2100 deterministic uat-groomer ↔ UAT Pup Alpha linkage (#151)
CI / Test (pull_request) Successful in 13s
CI / Lint & Typecheck (pull_request) Successful in 18s
CI / Build & Push Docker Images (pull_request) Successful in 45s
CI / Test (push) Successful in 2m20s
CI / Lint & Typecheck (push) Successful in 2m25s
CI / Build & Push Docker Images (push) Successful in 28s
2026-06-02 18:09:31 +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
The Dogfather 1a6a54cc84 security(audit): log owner-bypass reads in GET /pets/:id/profile-summary (GRO-2062) (#146)
CI / Test (push) Successful in 12s
CI / Lint & Typecheck (push) Successful in 16s
CI / Test (pull_request) Successful in 12s
CI / Lint & Typecheck (pull_request) Successful in 15s
CI / Build & Push Docker Images (push) Successful in 40s
CI / Build & Push Docker Images (pull_request) Successful in 27s
QA-approved (gb_lint) + CTO-approved. Defense-in-depth audit row on staff owner-bypass. GRO-2063.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-02 04:20:23 +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 a2b09ba502 fix(pets): port owner-bypass into deployed tree (GRO-2013) (#139)
CI / Test (push) Successful in 13s
CI / Lint & Typecheck (push) Successful in 16s
CI / Build & Push Docker Images (push) Successful in 1m5s
CI / Test (pull_request) Successful in 16s
CI / Lint & Typecheck (pull_request) Successful in 2m25s
CI / Build & Push Docker Images (pull_request) Failing after 32s
2026-06-01 20:06:24 +00:00
Flea Flicker 4322fb2a00 Merge pull request 'fix(db): re-register 0034/0036 schema changes via idempotent 0039/0040 (GRO-2033)' (#140) from flea/gro-2033-idempotent-pet-profile-migrations into dev
CI / Test (push) Successful in 12s
CI / Lint & Typecheck (push) Failing after 14m2s
CI / Build & Push Docker Images (push) Has been skipped
Merge PR #140: fix(db): re-register 0034/0036 schema changes via idempotent 0039/0040 (GRO-2033)
2026-06-01 20:00:41 +00:00