feat(seed): populate extended pet profile fields for UAT regression
GRO-1898: Ensure UAT seed data includes clients and pets with extended
profile fields (temperamentScore, temperamentFlags, medicalAlerts,
preferredCuts, coatType).
- Add data pools for extended profile fields in pet batch generation
- Populate all 5 extended fields for randomly generated pets
- Update UAT test client pets with fully populated extended profiles
- Fix type mismatches: medicalAlerts uses MedicalAlert[] with
{type, description, severity} shape per @groombook/types
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+73
-7
@@ -20,6 +20,7 @@ import postgres from "postgres";
|
|||||||
import { drizzle } from "drizzle-orm/postgres-js";
|
import { drizzle } from "drizzle-orm/postgres-js";
|
||||||
import { eq, and, sql } from "drizzle-orm";
|
import { eq, and, sql } from "drizzle-orm";
|
||||||
import * as schema from "./schema.js";
|
import * as schema from "./schema.js";
|
||||||
|
import type { MedicalAlert, MedicalAlertSeverity } from "./schema.js";
|
||||||
|
|
||||||
// ── Seed profile configuration ─────────────────────────────────────────────
|
// ── Seed profile configuration ─────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -252,6 +253,38 @@ const appointmentNotes = [
|
|||||||
"Client running late, pushed start by 15min",
|
"Client running late, pushed start by 15min",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const temperamentScores = [3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9];
|
||||||
|
|
||||||
|
const temperamentFlags = [
|
||||||
|
[], ["anxious"], ["friendly"], ["nippy"], ["anxious", "sensitive"],
|
||||||
|
["friendly", "calm"], ["nippy", "territorial"], ["calm"], ["sensitive"],
|
||||||
|
["friendly", "nippy"], ["anxious", "territorial"],
|
||||||
|
];
|
||||||
|
|
||||||
|
const medicalAlertsList = [
|
||||||
|
[] as MedicalAlert[],
|
||||||
|
[] as MedicalAlert[],
|
||||||
|
[{ type: "skin", description: "Sensitive skin — avoid harsh shampoos", severity: "medium" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "ear", description: "Ear infection prone — dry ears thoroughly", severity: "medium" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "mobility", description: "Hip dysplasia — handle with care", severity: "high" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "behavioral", description: "Anxious — needs slow approach", severity: "low" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "medical", description: "Seizure history — avoid stress triggers", severity: "high" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "skin", description: "Skin allergies — use hypoallergenic products only", severity: "medium" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "behavioral", description: "Aggressive when nails trimmed — muzzle required", severity: "high" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "cardiac", description: "Heart murmur — monitor during grooming", severity: "high" as MedicalAlertSeverity }],
|
||||||
|
[{ type: "dietary", description: "Diabetic — owner brings treats", severity: "medium" as MedicalAlertSeverity }],
|
||||||
|
];
|
||||||
|
|
||||||
|
const preferredCutsList = [
|
||||||
|
[], ["Puppy Cut"], ["Teddy Bear Cut"], ["Breed Standard"],
|
||||||
|
["Puppy Cut", "Sanitary Trim"], ["Full Groom"], ["Lion Cut"],
|
||||||
|
["Kennel Cut", "Face & Feet Trim"], ["Teddy Bear Cut", "Sanitary Trim"],
|
||||||
|
["Breed Standard", "Sanitary Trim"], ["Summer Shave"],
|
||||||
|
["Puppy Cut", "Face & Feet Trim", "Sanitary Trim"],
|
||||||
|
];
|
||||||
|
|
||||||
|
const coatTypes: string[] = ["short", "medium", "long", "curly", "wire", "double", "silky"];
|
||||||
|
|
||||||
const visitLogNotes = [
|
const visitLogNotes = [
|
||||||
null, null,
|
null, null,
|
||||||
"Coat in great condition",
|
"Coat in great condition",
|
||||||
@@ -872,6 +905,11 @@ async function seed() {
|
|||||||
cutStyle: pick(cutStyles),
|
cutStyle: pick(cutStyles),
|
||||||
shampooPreference: pick(shampoos),
|
shampooPreference: pick(shampoos),
|
||||||
specialCareNotes: rand() < 0.1 ? "Vet clearance required before grooming" : null,
|
specialCareNotes: rand() < 0.1 ? "Vet clearance required before grooming" : null,
|
||||||
|
coatType: pick(coatTypes),
|
||||||
|
temperamentScore: pick(temperamentScores),
|
||||||
|
temperamentFlags: pick(temperamentFlags),
|
||||||
|
medicalAlerts: pick(medicalAlertsList),
|
||||||
|
preferredCuts: pick(preferredCutsList),
|
||||||
customFields: {},
|
customFields: {},
|
||||||
image: petIndex < 250 ? pick(puggleImages) : pick(demoPetImages),
|
image: petIndex < 250 ? pick(puggleImages) : pick(demoPetImages),
|
||||||
});
|
});
|
||||||
@@ -907,6 +945,11 @@ async function seed() {
|
|||||||
cutStyle: pet.cutStyle,
|
cutStyle: pet.cutStyle,
|
||||||
shampooPreference: pet.shampooPreference,
|
shampooPreference: pet.shampooPreference,
|
||||||
specialCareNotes: pet.specialCareNotes,
|
specialCareNotes: pet.specialCareNotes,
|
||||||
|
coatType: pet.coatType,
|
||||||
|
temperamentScore: pet.temperamentScore,
|
||||||
|
temperamentFlags: pet.temperamentFlags,
|
||||||
|
medicalAlerts: pet.medicalAlerts,
|
||||||
|
preferredCuts: pet.preferredCuts,
|
||||||
customFields: pet.customFields,
|
customFields: pet.customFields,
|
||||||
image: pet.image,
|
image: pet.image,
|
||||||
},
|
},
|
||||||
@@ -929,13 +972,18 @@ async function seed() {
|
|||||||
petId: string;
|
petId: string;
|
||||||
petName: string;
|
petName: string;
|
||||||
petBreed: string;
|
petBreed: string;
|
||||||
|
petCoatType: string;
|
||||||
|
petTemperamentScore: number;
|
||||||
|
petTemperamentFlags: string[];
|
||||||
|
petMedicalAlerts: MedicalAlert[];
|
||||||
|
petPreferredCuts: string[];
|
||||||
}
|
}
|
||||||
const uatClients: UatClient[] = [
|
const uatClients: UatClient[] = [
|
||||||
{ id: uuid(), name: "UAT Test Alpha", email: "uat-alpha@groombook.dev", phone: "(555) 100-0001", address: "100 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestBuddy", petBreed: "Golden Retriever" },
|
{ id: uuid(), name: "UAT Test Alpha", email: "uat-alpha@groombook.dev", phone: "(555) 100-0001", address: "100 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestBuddy", petBreed: "Golden Retriever", petCoatType: "double", petTemperamentScore: 7, petTemperamentFlags: ["calm", "friendly"], petMedicalAlerts: [] as MedicalAlert[], petPreferredCuts: ["Breed Standard"] },
|
||||||
{ id: uuid(), name: "UAT Test Bravo", email: "uat-bravo@groombook.dev", phone: "(555) 100-0002", address: "200 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestMax", petBreed: "Labrador Retriever" },
|
{ id: uuid(), name: "UAT Test Bravo", email: "uat-bravo@groombook.dev", phone: "(555) 100-0002", address: "200 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestMax", petBreed: "Labrador Retriever", petCoatType: "short", petTemperamentScore: 8, petTemperamentFlags: ["friendly"], petMedicalAlerts: [] as MedicalAlert[], petPreferredCuts: ["Bath & Brush", "Sanitary Trim"] },
|
||||||
{ id: uuid(), name: "UAT Test Charlie", email: "uat-charlie@groombook.dev", phone: "(555) 100-0003", address: "300 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestCooper", petBreed: "Poodle" },
|
{ id: uuid(), name: "UAT Test Charlie", email: "uat-charlie@groombook.dev", phone: "(555) 100-0003", address: "300 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestCooper", petBreed: "Poodle", petCoatType: "curly", petTemperamentScore: 9, petTemperamentFlags: ["calm"], petMedicalAlerts: [{ type: "behavioral", description: "Anxious — needs slow approach", severity: "low" as MedicalAlertSeverity }], petPreferredCuts: ["Teddy Bear Cut"] },
|
||||||
{ id: uuid(), name: "UAT Test Delta", email: "uat-delta@groombook.dev", phone: "(555) 100-0004", address: "400 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestRocky", petBreed: "French Bulldog" },
|
{ id: uuid(), name: "UAT Test Delta", email: "uat-delta@groombook.dev", phone: "(555) 100-0004", address: "400 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestRocky", petBreed: "French Bulldog", petCoatType: "short", petTemperamentScore: 6, petTemperamentFlags: ["nippy"], petMedicalAlerts: [{ type: "skin", description: "Sensitive skin — avoid harsh shampoos", severity: "medium" as MedicalAlertSeverity }], petPreferredCuts: ["Puppy Cut"] },
|
||||||
{ id: uuid(), name: "UAT Test Echo", email: "uat-echo@groombook.dev", phone: "(555) 100-0005", address: "500 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestDuke", petBreed: "Beagle" },
|
{ id: uuid(), name: "UAT Test Echo", email: "uat-echo@groombook.dev", phone: "(555) 100-0005", address: "500 Test Lane, Springfield, CA 90210", petId: uuid(), petName: "TestDuke", petBreed: "Beagle", petCoatType: "short", petTemperamentScore: 7, petTemperamentFlags: ["friendly", "energetic"], petMedicalAlerts: [] as MedicalAlert[], petPreferredCuts: ["Full Groom", "Nail Trim"] },
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const uc of uatClients) {
|
for (const uc of uatClients) {
|
||||||
@@ -943,8 +991,26 @@ async function seed() {
|
|||||||
.values({ id: uc.id, name: uc.name, email: uc.email, phone: uc.phone, address: uc.address })
|
.values({ id: uc.id, name: uc.name, email: uc.email, phone: uc.phone, address: uc.address })
|
||||||
.onConflictDoUpdate({ target: schema.clients.id, set: { name: uc.name, email: uc.email, phone: uc.phone, address: uc.address } });
|
.onConflictDoUpdate({ target: schema.clients.id, set: { name: uc.name, email: uc.email, phone: uc.phone, address: uc.address } });
|
||||||
await db.insert(schema.pets)
|
await db.insert(schema.pets)
|
||||||
.values({ id: uc.petId, clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"), image: pick(demoPetImages) })
|
.values({
|
||||||
.onConflictDoUpdate({ target: schema.pets.id, set: { clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"), image: pick(demoPetImages) } });
|
id: uc.petId, clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed,
|
||||||
|
weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"),
|
||||||
|
coatType: uc.petCoatType,
|
||||||
|
temperamentScore: uc.petTemperamentScore,
|
||||||
|
temperamentFlags: uc.petTemperamentFlags,
|
||||||
|
medicalAlerts: uc.petMedicalAlerts,
|
||||||
|
preferredCuts: uc.petPreferredCuts,
|
||||||
|
image: pick(demoPetImages),
|
||||||
|
})
|
||||||
|
.onConflictDoUpdate({ target: schema.pets.id, set: {
|
||||||
|
clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed,
|
||||||
|
weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"),
|
||||||
|
coatType: uc.petCoatType,
|
||||||
|
temperamentScore: uc.petTemperamentScore,
|
||||||
|
temperamentFlags: uc.petTemperamentFlags,
|
||||||
|
medicalAlerts: uc.petMedicalAlerts,
|
||||||
|
preferredCuts: uc.petPreferredCuts,
|
||||||
|
image: pick(demoPetImages),
|
||||||
|
} });
|
||||||
// Create one completed appointment for this client
|
// Create one completed appointment for this client
|
||||||
const apptId = uuid();
|
const apptId = uuid();
|
||||||
const svcIdx = 0;
|
const svcIdx = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user