Commit Graph

22 Commits

Author SHA1 Message Date
Flea Flicker 948806bf09 fix(db): set isSuperUser=false for Jordan Lee in full seed path
Gro-511: Jordan Lee (manager account) was created with isSuperUser=true
in the full seed path, causing GET /api/setup/status to return
needsSetup=false and blocking the OOBE flow after UAT reset.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 03:22:43 +00:00
groombook-engineer[bot] 74571d9f2b feat(demo): expand demo pet images and seed data with diverse breed showcase
Generated 16 diverse pet images for demo site using MiniMax image generation:
- Multiple dog breeds (Golden Retriever, Poodle, Labrador, Shih Tzu, Cocker Spaniel, Schnauzer, Maltese, Dachshund, Pomeranian)
- Professional grooming styles and poses
- Studio lighting for quality showcase

Updated seed.ts to create 9 demo pets with image references:
- Expands from single demo pet to diverse pet portfolio
- Images deployed to apps/web/public/demo-pets/
- Each pet has breed-accurate styling and professional grooming

This completes GRO-395 demo assets expansion using allocated MiniMax credits.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-02 12:15:21 +00:00
groombook-engineer[bot] 3d9021913d feat(branding): add GroomBook logo and demo pet images for demo site
- Generated professional GroomBook logo using brand colors (sage green & warm brown)
- Created 4 realistic test pet images (Golden Retriever, Labrador, Poodle, Mixed Breed)
- Updated demo seed to reference pet image in demo database
- Assets are reloaded with demo data going forward

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-02 11:49:43 +00:00
groombook-engineer[bot] 5a09290d9f fix(db): move impersonation TRUNCATE before staff upsert to avoid FK violation
The TRUNCATE of impersonation_sessions/audit_logs was running after the
staff upsert. When a prior seed left impersonation_sessions rows
referencing staff records, ON CONFLICT DO UPDATE on staff violated the
FK constraint on impersonation_sessions.staff_id.

Moving the TRUNCATE before the staff block ensures all impersonation rows
are cleared before any staff insert/update attempt.

Co-authored-by: groombook-engineer[bot] <3141748+groombook-engineer[bot]@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-02 01:03:36 +00:00
groombook-engineer[bot] ee803b4376 fix(db): add impersonation_sessions and audit_logs to seed TRUNCATE chain (#200)
Truncate these tables before staff upsert to avoid FK constraint violations
when the dev DB already has impersonation sessions referencing staff rows.

Co-authored-by: groombook-engineer[bot] <3141748+groombook-engineer[bot]@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: groombook-ceo[bot] <269735724+groombook-ceo[bot]@users.noreply.github.com>
2026-04-01 21:24:58 +00:00
groombook-ceo[bot] 361567dc3b Merge branch 'main' into fix/gro-360-yq-compound-assignment 2026-04-01 19:56:01 +00:00
groombook-engineer[bot] dff11d02be fix(db): seed staff_id FK fix (GRO-369)
Fixes staff_id FK violation on re-seed: move TRUNCATE before staff upsert and add id to onConflictDoUpdate set clause.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-01 14:19:49 +00:00
groombook-engineer[bot] cfa28c64b6 fix(db): add migration 0020 for UNIQUE(name) + align admin seed ON CONFLICT
Problem:
- Schema change in eacf8ab added .unique() to services.name
- No migration existed to apply this constraint to the database
- Admin seed and seedKnownUsers still used ON CONFLICT (id) with
  a0000001-... IDs, inconsistent with main seed's b0000001-... IDs
  and ON CONFLICT (name)

Fix:
- Migration 0020: clean up existing duplicate services (keep lowest
  id per name), then add UNIQUE constraint on services.name
- Admin seed (apps/api): switch to ON CONFLICT (name) and b0000001
  IDs to match main seed's servicesDef
- seedKnownUsers (packages/db): same alignment — b0000001 IDs and
  ON CONFLICT (name)

GRO-364: ON CONFLICT (name) eliminates the duplicate-row problem
that the old dedup+ON CONFLICT(id) approach could not solve when
existing rows had non-deterministic IDs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-01 13:54:54 +00:00
groombook-engineer[bot] 7033cd1d5c fix(db): remove dedup DELETE and use ON CONFLICT (name) for idempotent services seed
The dedup DELETE was causing two problems:
1. FK violation (GRO-365) — deleting services referenced by appointments
2. Duplicate services (GRO-301) — MIN(id) per name could delete the wrong row,
   causing ON CONFLICT (id) to create duplicates on re-run

Fix:
- Remove the dedup DELETE entirely
- Keep TRUNCATE of downstream tables (appointments, invoices, etc.) to clear
  stale data from prior runs
- Change ON CONFLICT target from `id` to `name` with a unique constraint on
  name column — deterministic IDs in servicesDef ensure idempotency

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-01 13:54:54 +00:00
groombook-engineer[bot] 07263a89fe fix(db): truncate downstream tables before services dedup to avoid FK violation (#197)
TRUNCATE appointments, invoices, invoice_line_items, invoice_tip_splits,
and grooming_visit_logs CASCADE before the services dedup DELETE to prevent
FK violations from appointments created by previous seed runs.

Fixes: GRO-365

Co-authored-by: groombook-engineer[bot] <3141748+groombook-engineer[bot]@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-01 13:21:31 +00:00
groombook-engineer[bot] 034b733f74 fix(db): cast uuid to text for MIN() in services dedup query (GRO-364)
Postgres has no built-in MIN() aggregate for UUID type.
Cast to text before aggregating, then cast back to uuid.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-01 12:25:43 +00:00
Barkley Trimsworth 6277b1c427 Merge remote-tracking branch 'origin/main' into fix/gro-309-landing-page-redirect 2026-04-01 03:43:40 +00:00
groombook-engineer[bot] 2fd86d0636 fix(api): use UTC in reports date helpers — reports show no data (GRO-302)
Fixes GRO-302. Reports page showed no data because date range helpers used local time instead of UTC for boundary calculations.
2026-03-31 19:47:30 +00:00
Barkley Trimsworth d4bdca5616 fix(db): restore serviceIds array used in appointment seed lookups
The serviceIds array is referenced by later appointment creation code.
Restore it inside the services loop.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 18:43:35 +00:00
Barkley Trimsworth 6974ca88a8 fix(db): use deterministic service IDs and add deduplication step
Replace random uuid() for service IDs with pre-assigned deterministic
UUIDs (b0000001-0000-0000-0000-...) so that ON CONFLICT DO UPDATE
correctly targets the id column and prevents duplicate inserts.

Also add a one-time deduplication query before inserting that removes
any existing duplicate service rows (keeps lowest id per name), which
cleans up the current deployed database that already has duplicates.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 18:38:33 +00:00
groombook-engineer[bot] 40143c4efa fix(db): seed ON CONFLICT target uses clients.id instead of non-unique clients.email
Fixes seed script crash — both onConflictDoUpdate calls on clients table now use schema.clients.id (PK) as conflict target instead of non-unique schema.clients.email. Email added to set clause for both call sites.

Resolves GRO-298. Unblocks GRO-290, GRO-295, GRO-297.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-30 14:44:38 +00:00
groombook-ci[bot] b06314efe2 fix(db): guarantee 5 UAT test clients with pending invoices (GRO-290)
Before: ~5% probabilistic pending invoices meant UAT couldn't reliably
find billing test data. Shedward was blocked from testing Pay Now flows.

After: deterministic 5 UAT clients (uat-alpha through uat-echo) each get
a completed appointment + pending invoice on every seed run. Client
names and emails documented in Shedward AGENTS.md for direct access.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-30 13:33:53 +00:00
groombook-ci[bot] eb48d97ee3 fix(db): make seed script idempotent using upserts
Convert raw inserts to upserts (ON CONFLICT DO UPDATE) for:
- staff: upsert on email (unique constraint)
- services: upsert on id (deterministic UUID)
- clients: upsert on email (unique constraint)
- pets: upsert on id (deterministic UUID)

This fixes the duplicate key violation when re-running the seed
script against an existing database (e.g., after schema migrations
or test restarts).

Note: appointments, invoices, visit logs still use raw inserts
and would need DELETE-before-insert for full idempotency. Those
tables use deterministic UUIDs so a second seed run without
prior DELETE would still fail. This is scoped to the immediate
staff email constraint violation reported.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-29 02:23:02 +00:00
groombook-engineer[bot] 3a31ad71c2 feat(schema): add is_super_user to staff table (GRO-201)
Add boolean is_super_user column (default false) to staff table.
Update Staff interface in shared types.
Mark first manager as super user in both seed modes.
Update test fixtures to include isSuperUser field.

Co-authored-by: groombook-ci[bot] <ci@groombook.bot>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:39:46 +00:00
groombook-engineer[bot] e3220af9ce fix(gro-38): prod/demo auth and API-based seed (#117)
Closes GRO-38. Adds POST /api/admin/seed (manager-only, gated by SEED_KNOWN_USERS_ONLY) and separates dev vs prod seeding paths. Reviewed and approved by CTO and QA.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-26 20:51:08 +00:00
Scrubs McBarkley ad6024f3d9 feat: deterministic seed, impersonation migration, test factories (GRO-110)
Phase 1 — Seed Hardening:
- Replace all Math.random() calls in seed.ts with a Mulberry32 seeded PRNG
  (seed 42) so the same data set is reproduced on every run
- Replace crypto.randomUUID() with a PRNG-based UUID v4 generator
- Add manager (Jordan Lee) and receptionist (Sam Rivera) staff members
  to seed — previously all staff were groomers
- New packages/db/src/reset.ts drops all tables/enums and re-runs
  migrate + seed; exposed as `pnpm db:reset` at root
- Generate migration 0010_impersonation_sessions.sql for the
  impersonation_sessions and impersonation_audit_logs tables that were
  already in schema.ts but had no corresponding migration

Phase 2 — Test Factories:
- New packages/db/src/factories.ts with buildStaff, buildClient, buildPet,
  buildService, buildAppointment and resetFactoryCounters helpers
- Exported via @groombook/db/factories subpath (package.json + vitest alias)
- impersonation.test.ts updated to use buildStaff instead of hand-rolled
  fixture objects

Closes #90 (Phases 1 + 2)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-21 19:34:52 +00:00
groombook-paperclip[bot] 20fa4698be Add test data seed script with 500 clients, 6 staff, and appointments (#36)
Creates packages/db/src/seed.ts that generates realistic development data:
- 3 groomers + 3 bathers (staff)
- 10 grooming services
- 500 clients with 1-3 dogs each
- ~2500 appointments across 12 months with varied statuses
- Invoices with line items and tip splits for completed appointments
- Grooming visit logs

Run via: pnpm db:seed (requires DATABASE_URL)

Co-authored-by: Groom Book CEO <ceo@groombook.dev>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-17 23:37:18 +00:00