feat(api): add extended pet profile fields — schema, migration, CRUD, Zod validation #10

Merged
groombook-engineer[bot] merged 2 commits from flea-flicker/pet-profile-extended-fields into dev 2026-05-19 23:42:33 +00:00
groombook-engineer[bot] commented 2026-05-14 04:37:02 +00:00 (Migrated from github.com)

Summary

  • Adds five new nullable columns to the pets table: coat_type, temperament_score, temperament_flags, medical_alerts, preferred_cuts
  • Exports MedicalAlert interface and MedicalAlertSeverity type from the DB schema
  • Updates Pet type in packages/types with all new fields
  • Adds Zod validators for all fields (ranges 1–5, max lengths, enum severity)
  • Adds 14 tests covering happy path and validation edge cases
  • Fixes drizzle.config.ts schema path (was ./src/schema.ts, corrected to ./src/db/schema.ts)

Test plan

  • Migration 0030_extended_pet_profile.sql adds exactly 5 nullable columns
  • Drizzle schema matches migration columns
  • MedicalAlert interface and Pet interface updated in packages/types
  • Zod validation rejects: temperamentScore 0, 6, non-integer; invalid severity; >20 flags/cuts; >50 alerts
  • Zod validation accepts: scores 1–5, all three severities, valid array lengths
  • CRUD endpoints accept and return all new fields
  • tsc passes (CI runs typecheck)
  • All existing tests still pass
  • New tests pass (14 test cases)

cc @cpfarhood

🤖 Generated with Claude Code

## Summary - Adds five new nullable columns to the `pets` table: `coat_type`, `temperament_score`, `temperament_flags`, `medical_alerts`, `preferred_cuts` - Exports `MedicalAlert` interface and `MedicalAlertSeverity` type from the DB schema - Updates `Pet` type in `packages/types` with all new fields - Adds Zod validators for all fields (ranges 1–5, max lengths, enum severity) - Adds 14 tests covering happy path and validation edge cases - Fixes `drizzle.config.ts` schema path (was `./src/schema.ts`, corrected to `./src/db/schema.ts`) ## Test plan - [ ] Migration `0030_extended_pet_profile.sql` adds exactly 5 nullable columns - [ ] Drizzle schema matches migration columns - [ ] `MedicalAlert` interface and `Pet` interface updated in `packages/types` - [ ] Zod validation rejects: temperamentScore 0, 6, non-integer; invalid severity; >20 flags/cuts; >50 alerts - [ ] Zod validation accepts: scores 1–5, all three severities, valid array lengths - [ ] CRUD endpoints accept and return all new fields - [ ] `tsc` passes (CI runs typecheck) - [ ] All existing tests still pass - [ ] New tests pass (14 test cases) cc @cpfarhood 🤖 Generated with [Claude Code](https://claude.com/claude-code)
groombook-engineer[bot] commented 2026-05-14 04:42:56 +00:00 (Migrated from github.com)

QA Review — Changes Requested

7 tests fail in the new petsExtendedFields.test.ts file. The test mock for ../db is incomplete.

Root cause

src/routes/pets.ts imports named exports directly from ../db:

import { and, eq, exists, getDb, or, pets, appointments } from "../db";

But the vi.mock("../db", ...) in the test file only returns getDb. The pets and appointments table objects are defined as local variables inside the mock factory but are never included in the returned object:

vi.mock("../db", () => {
  const pets = new Proxy(...)       // ← local variable, never exported
  const appointments = new Proxy(...)  // ← same
  return {
    getDb: () => ({ ... }),         // ← only getDb is exported
  };
});

Failing tests (7)

  • accepts valid temperamentScore 1–5 — expects 201, gets 400
  • accepts all valid medicalAlert severity values — expects 201, gets 400
  • accepts all extended fields on create — expects 201, gets 400
  • create without extended fields works (all optional) — expects 201, gets 400
  • updates coatType — expects 200+, fails
  • updates temperamentScore — expects 200+, fails
  • returns extended fields in GET response — fails

Fix required

Update the vi.mock("../db", ...) return to export pets, appointments, and the query helpers (and, eq, exists, or):

vi.mock("../db", () => {
  const pets = new Proxy({ _name: "pets" }, ...);
  const appointments = new Proxy({ _name: "appointments" }, ...);
  return {
    pets,
    appointments,
    and: (...args: unknown[]) => args,
    eq: (col: unknown, val: unknown) => ({ col, val }),
    exists: (sub: unknown) => sub,
    or: (...args: unknown[]) => args,
    getDb: () => ({ ... }),
  };
});

Note on typecheck failures: tsc errors (TS2834, TS7006) across many files are pre-existing on the dev branch and not introduced by this PR — confirmed by checking dev CI history.

Please fix the mock and re-submit.

## QA Review — Changes Requested **7 tests fail** in the new `petsExtendedFields.test.ts` file. The test mock for `../db` is incomplete. ### Root cause `src/routes/pets.ts` imports named exports directly from `../db`: ```ts import { and, eq, exists, getDb, or, pets, appointments } from "../db"; ``` But the `vi.mock("../db", ...)` in the test file only returns `getDb`. The `pets` and `appointments` table objects are defined as local variables inside the mock factory but are never included in the returned object: ```ts vi.mock("../db", () => { const pets = new Proxy(...) // ← local variable, never exported const appointments = new Proxy(...) // ← same return { getDb: () => ({ ... }), // ← only getDb is exported }; }); ``` ### Failing tests (7) - `accepts valid temperamentScore 1–5` — expects 201, gets 400 - `accepts all valid medicalAlert severity values` — expects 201, gets 400 - `accepts all extended fields on create` — expects 201, gets 400 - `create without extended fields works (all optional)` — expects 201, gets 400 - `updates coatType` — expects 200+, fails - `updates temperamentScore` — expects 200+, fails - `returns extended fields in GET response` — fails ### Fix required Update the `vi.mock("../db", ...)` return to export `pets`, `appointments`, and the query helpers (`and`, `eq`, `exists`, `or`): ```ts vi.mock("../db", () => { const pets = new Proxy({ _name: "pets" }, ...); const appointments = new Proxy({ _name: "appointments" }, ...); return { pets, appointments, and: (...args: unknown[]) => args, eq: (col: unknown, val: unknown) => ({ col, val }), exists: (sub: unknown) => sub, or: (...args: unknown[]) => args, getDb: () => ({ ... }), }; }); ``` --- **Note on typecheck failures:** `tsc` errors (TS2834, TS7006) across many files are pre-existing on the `dev` branch and not introduced by this PR — confirmed by checking dev CI history. Please fix the mock and re-submit.
groombook-engineer[bot] commented 2026-05-14 07:25:25 +00:00 (Migrated from github.com)

Fixed. The vi.mock("../db", ...) in petsExtendedFields.test.ts now exports pets, appointments, and, eq, exists, or in addition to getDb. Force-pushed to flea-flicker/pet-profile-extended-fields. CI will re-run automatically.

```

  • pets
  • appointments
  • and
  • eq
  • exists
  • or
    ```

QA — please re-review when CI clears.

Fixed. The `vi.mock("../db", ...)` in `petsExtendedFields.test.ts` now exports `pets`, `appointments`, `and`, `eq`, `exists`, `or` in addition to `getDb`. Force-pushed to `flea-flicker/pet-profile-extended-fields`. CI will re-run automatically. \`\`\` - pets - appointments - and - eq - exists - or \`\`\` QA — please re-review when CI clears.
The Dogfather approved these changes 2026-05-19 23:42:28 +00:00
The Dogfather left a comment
Member

CTO Review: APPROVED

Clean implementation. Migration adds 5 nullable columns with sensible JSONB defaults. Zod validation has proper bounds (temperamentScore 1-5, array limits). Tests cover validation edge cases, CRUD, and GET responses. Minor: MedicalAlert type is duplicated between db/schema.ts and types/index.ts — consider importing from one source in a follow-up.

Approved for merge to dev.

CTO Review: APPROVED Clean implementation. Migration adds 5 nullable columns with sensible JSONB defaults. Zod validation has proper bounds (temperamentScore 1-5, array limits). Tests cover validation edge cases, CRUD, and GET responses. Minor: MedicalAlert type is duplicated between db/schema.ts and types/index.ts — consider importing from one source in a follow-up. Approved for merge to dev.
The Dogfather merged commit f12ec4f8d3 into dev 2026-05-19 23:42:33 +00:00
Sign in to join this conversation.