Commit Graph

34 Commits

Author SHA1 Message Date
Test User c76ea93c29 fix(GRO-818): refund button for all paid invoices, inline cardLast4, manual refund for non-Stripe
- Backend refund endpoint: allow refunds on paid invoices without stripePaymentIntentId (manual refund path)
- Backend GET /invoices/🆔 inline fetch cardLast4 + paymentStatus from Stripe when stripePaymentIntentId present
- Frontend: show Refund button on all paid invoices for managers (not just Stripe-backed ones)
- Seed: add stripePaymentIntentId (pi_test_*) to ~20% of paid invoices for Stripe-path testing

cc @cpfarhood
2026-04-24 16:18:48 +00:00
groombook-engineer[bot] edf2ef8f7e fix(GRO-666): leave staff.user_id NULL in seed so middleware can auto-link by email (#314)
The resolveStaffMiddleware auto-links on first API call when staff.user_id
IS NULL. Setting userId at seed time blocks this path since Better-Auth's
user.id is opaque and unknown pre-auth. Remove userId from all staff inserts
so the middleware can populate it on first authenticated call.

Co-authored-by: Test User <test@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-17 06:35:33 +00:00
Flea Flicker 29a726fa3d feat(GRO-690): add groomer persona seed support via env vars
Extend seed.ts with SEED_UAT_GROOMER_EMAILS and SEED_UAT_GROOMER_NAMES
env vars for persistent groomer personas (sam@sarah). Works in both
SEED_KNOWN_USERS_ONLY=true and full seed modes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:04:52 +00:00
Flea Flicker 16dd513521 fix(seed): populate userId for UAT staff and SEED_ADMIN_EMAIL staff
GRO-666: resolveStaffMiddleware returns 403 for UAT users because
staff records have NULL userId after seed. This change populates
userId (and oidcSub) for all staff created via seedKnownUsers()
and the main seed path using the same value as the OIDC sub.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-15 09:37:51 +00:00
groombook-ceo[bot] 4fa4859eaf fix: set Manager 1 as super user in UAT seed to resolve OOBE redirect
Co-authored-by: Flea Flicker <flea-flicker@paperclip.ing>
Co-authored-by: groombook-cto[bot] <269737991+groombook-cto[bot]@users.noreply.github.com>
2026-04-15 00:47:09 +00:00
Paperclip c919632aea fix(GRO-395): adjust Puggle image array to 4 available images
Removed reference to tricolor-outdoor image that experienced API timeout.
Seed now uses 4 successfully generated Puggle-specific images for the
first 250 seeded pets, ensuring all referenced images exist in demo-pets.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-11 02:22:05 +00:00
Paperclip 522e5dbf63 feat(GRO-395): ensure at least 250 seeded pets are Puggles with photos
Add Puggle breed to dogBreeds array and modify seed logic to guarantee first 250 pets are assigned Puggle breed. This ensures demo data includes a significant population of Puggle dogs (Pug-Beagle mix) with images for testing grooming workflows with diverse pet breeds.

- Add Puggle to available dog breeds list
- Track pet creation index across all clients
- Assign Puggle breed to first 250 pets regardless of randomization
- Assign Puggle-specific images to first 250 pets
- Remaining pets use general demo image pool

This satisfies requirement: "at least 250 of the 2500 pets are first or second generation puggles with photos"

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-10 21:45:16 +00:00
Paperclip 39f603589b feat(GRO-395): expand demo pet image library with 13 AI-generated diverse dog images
- Generated 13 new diverse dog images using MiniMax (Afghan Hound, Basset Hound, Bichon Frise variants, Boxer, Cavalier, Cocker Spaniel variants, Corgi, Dachshund variants, Pomeranian variants, Schnauzer variants, Setter, Sheepdog)
- Updated seed script to include all 28 dog images in demoPetImages array
- Ensures wider variety of dog breeds and grooming styles in demo seed data
- All images are photorealistic and suitable for pet grooming demo site

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 21:40:09 +00:00
Paperclip 2ab06853e6 fix(GRO-395): add demo pet images to seed data for all profiles
- Add demoPetImages array with 15 available dog images
- Assign random pet images during seed for regular, UAT, and demo profiles
- Ensures demo site displays pet images instead of missing images

The seed script previously only added images for seedKnownUsers mode.
Now all seeded pets get assigned a random demo pet image.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 21:18:10 +00:00
Flea Flicker fafb717e5a feat(GRO-537): add UAT Super User and Staff Groomer to seed script
In seedKnownUsers(), add staff records for UAT Super User
(manager, superuser) and UAT Staff Groomer (groomer) with oidcSub
read from SEED_UAT_SUPER_OIDC_SUB and SEED_UAT_STAFF_OIDC_SUB
env vars. Only creates records when the env vars are present.
Idempotent: skips if email already exists.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 10:48:11 +00:00
groombook-engineer[bot] 1255fd91cd feat: parameterize seed script with SEED_PROFILE env var (GRO-526)
Adds SEED_PROFILE env var accepting 'dev', 'uat', or 'demo' values:

- dev: 4 staff (1 manager, 1 receptionist, 2 groomers), 100 clients,
  7d/30d appointment window, ~1000 invoices, no UAT clients
- uat: 8 staff (1 manager, 1 receptionist, 3 groomers, 3 bathers),
  500 clients, 30d/90d window, ~4000 invoices, includes UAT clients
- demo: same volume as uat

Unset SEED_PROFILE defaults to 'uat' for backwards compatibility.
SEED_KNOWN_USERS_ONLY=true path unchanged.
All appointment dates computed relative to NOW() at seed time.
Supplemental completed appointments generated when profile invoice
target exceeds organic appointment count.

Closes groombook/groombook#247

Co-authored-by: Flea Flicker <flea-flicker@groombook.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-10 04:00:37 +00:00
Flea Flicker 63256b8bc0 feat: implement SEED_ADMIN_EMAIL support in seedKnownUsers and full seed
- Add admin upsert to seedKnownUsers() for prod path
- Add admin upsert to seed() for UAT path
- Idempotent: skips if SEED_ADMIN_EMAIL not set

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 22:33:15 +00:00
Paperclip a84d5e7b9a fix: set isSuperUser=false for Jordan Lee in full seed
Jordan Lee was being created with isSuperUser=true in the full seed path,
causing GET /api/setup/status to return needsSetup=false after UAT reset.
2026-04-08 02:56:31 +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