From ca497774aaa61f1add789f2917540959c3469ed3 Mon Sep 17 00:00:00 2001 From: Flea Flicker <22+gb_flea@noreply.git.farh.net> Date: Tue, 9 Jun 2026 08:56:22 +0000 Subject: [PATCH] GRO-2172: add missing extended pet fields to create/update schemas (#199) --- src/routes/pets.ts | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/routes/pets.ts b/src/routes/pets.ts index 5c4aaec..229a047 100644 --- a/src/routes/pets.ts +++ b/src/routes/pets.ts @@ -57,6 +57,23 @@ const createPetSchema = z.object({ customFields: z.record(z.string(), z.string()).optional(), petSizeCategory: z.enum(["small", "medium", "large", "extra_large"]).optional(), coatType: z.enum(["short", "medium", "long", "double", "wire", "silky", "curly", "hairless"]).optional(), + // Extended pet profile fields (api/#39, GRO-1178). + // GRO-2172: these were missing from the schema, causing POST/PATCH to + // silently drop them even though migrations 0034/0036 and seed data + // populate them. GRO-1472 was the original UAT regression. + temperamentScore: z.number().int().min(1).max(5).optional(), + temperamentFlags: z.array(z.string().max(100)).max(20).optional(), + medicalAlerts: z + .array( + z.object({ + type: z.string().max(100), + description: z.string().max(1000), + severity: z.enum(["low", "medium", "high"]), + }) + ) + .max(50) + .optional(), + preferredCuts: z.array(z.string().max(200)).max(20).optional(), }); const updatePetSchema = createPetSchema.partial().omit({ clientId: true }); @@ -333,7 +350,8 @@ petsRouter.get("/:id/profile-summary", async (c) => { petsRouter.post("/", zValidator("json", createPetSchema), async (c) => { const db = getDb(); - const { weightKg, dateOfBirth, customFields, ...rest } = c.req.valid("json"); + const { weightKg, dateOfBirth, customFields, medicalAlerts, ...rest } = + c.req.valid("json"); const [row] = await db .insert(pets) .values({ @@ -341,6 +359,10 @@ petsRouter.post("/", zValidator("json", createPetSchema), async (c) => { weightKg: weightKg?.toString(), dateOfBirth: dateOfBirth ? new Date(dateOfBirth) : undefined, customFields: customFields ?? {}, + // GRO-2172: medicalAlerts shape from the API request is + // { type, description, severity } — the @groombook/types MedicalAlert + // has an optional server-generated `id`, so cast for the jsonb column. + medicalAlerts: medicalAlerts as never, }) .returning(); return c.json(row, 201); @@ -351,7 +373,8 @@ petsRouter.patch( zValidator("json", updatePetSchema), async (c) => { const db = getDb(); - const { weightKg, dateOfBirth, customFields, ...rest } = c.req.valid("json"); + const { weightKg, dateOfBirth, customFields, medicalAlerts, ...rest } = + c.req.valid("json"); const [row] = await db .update(pets) .set({ @@ -359,6 +382,7 @@ petsRouter.patch( weightKg: weightKg?.toString(), dateOfBirth: dateOfBirth ? new Date(dateOfBirth) : undefined, ...(customFields !== undefined ? { customFields } : {}), + medicalAlerts: medicalAlerts as never, updatedAt: new Date(), }) .where(eq(pets.id, c.req.param("id"))) -- 2.52.0