diff --git a/UAT_PLAYBOOK.md b/UAT_PLAYBOOK.md index f4d1cd8..c0369f1 100644 --- a/UAT_PLAYBOOK.md +++ b/UAT_PLAYBOOK.md @@ -79,7 +79,7 @@ GroomBook is an open-source, self-hostable pet grooming business management & CR | TC-APP-4.5.5 | Appointment groups | 1. Create multiple appointments for same time slot
2. View in calendar | Appointments are grouped/linked appropriately | | TC-APP-4.5.6 | Appointment availability check | 1. Attempt to book appointment during unavailable slot | System shows conflict or prevents double-booking | | TC-APP-4.5.7 | Booking wizard — size/coat selection | 1. Start new appointment booking wizard
2. Select a pet with sizeCategory and coatType set
3. Observe the service/slot selection step | Size and coat type dropdowns are displayed and persist the pet's existing values | -| TC-APP-4.5.8 | Large/X-Large pet slot duration reflects buffer | 1. Add a pet with sizeCategory = "large" or "x-large" to an appointment
2. Note the service duration
3. Complete booking and inspect the appointment | Appointment slot includes the service duration plus the configured buffer for the pet's size category | +| TC-APP-4.5.8 | Large/Xlarge pet slot duration reflects buffer | 1. Add a pet with sizeCategory = "large" or "xlarge" to an appointment
2. Note the service duration
3. Complete booking and inspect the appointment | Appointment slot includes the service duration plus the configured buffer for the pet's size category | | TC-APP-4.5.9 | Appointment overrun cascades downstream | 1. Book three consecutive same-groomer appointments (A → B → C)
2. Manually extend appointment A's endTime so it overlaps B's startTime by ≥15 min
3. Observe appointment B | Appointment B (and C if still overlapping) is automatically shifted forward by the overrun delta + buffer; no error thrown | | TC-APP-4.5.10 | Cascaded appointments appear at new times | 1. Complete TC-APP-4.5.9
2. Check the calendar/list view | Appointments B and C are now shown at their shifted start/end times | | TC-APP-4.5.11 | Client receives reschedule notification email | 1. Complete TC-APP-4.5.9
2. Check the client's email (or notification log) | Client receives an email with subject/lines indicating their appointment was rescheduled from original time to new time | diff --git a/apps/api/src/lib/cascade.ts b/apps/api/src/lib/cascade.ts index ea9f66e..a4c8ae1 100644 --- a/apps/api/src/lib/cascade.ts +++ b/apps/api/src/lib/cascade.ts @@ -1,4 +1,4 @@ -import { eq, and, gt, gte, lt, ne, or, asc } from "@groombook/db"; +import { eq, and, gt, or, asc } from "@groombook/db"; import { appointments, clients, pets, services, staff, type Db } from "@groombook/db"; import { resolveBufferMinutes } from "./buffer.js"; import { sendEmail, buildRescheduleNotificationEmail } from "../services/email.js"; @@ -53,12 +53,12 @@ export async function detectAndCascadeOverrun({ db, overrunningAppointmentId, newEndTime, - originalEndTime, + _originalEndTime, }: { db: Db; overrunningAppointmentId: string; newEndTime: Date; - originalEndTime: Date; + _originalEndTime: Date; }): Promise { const result: CascadeResult = { shifted: [], flaggedForReview: [] }; @@ -178,16 +178,16 @@ export async function detectAndCascadeOverrun({ export function isOverrun({ originalEndTime, newEndTime, - originalStartTime, - newStartTime, + _originalStartTime, + _newStartTime, status, currentTime, bufferMinutes, }: { originalEndTime: Date; newEndTime: Date; - originalStartTime: Date; - newStartTime?: Date; + _originalStartTime: Date; + _newStartTime?: Date; status: string; currentTime: Date; bufferMinutes: number; diff --git a/apps/api/src/routes/appointments.ts b/apps/api/src/routes/appointments.ts index af171d2..46a36c2 100644 --- a/apps/api/src/routes/appointments.ts +++ b/apps/api/src/routes/appointments.ts @@ -700,7 +700,7 @@ appointmentsRouter.patch( isOverrun({ originalEndTime, newEndTime: new Date(updateFields.endTime), - originalStartTime: row.startTime, + _originalStartTime: row.startTime, status: row.status, currentTime: new Date(), bufferMinutes: row.bufferMinutes ?? 0, @@ -710,7 +710,7 @@ appointmentsRouter.patch( db, overrunningAppointmentId: id, newEndTime: new Date(updateFields.endTime), - originalEndTime, + _originalEndTime: originalEndTime, }); return c.json({ ...row, cascade: cascadeResult }); } diff --git a/apps/api/src/routes/book.ts b/apps/api/src/routes/book.ts index 3fb61c9..bd6fa67 100644 --- a/apps/api/src/routes/book.ts +++ b/apps/api/src/routes/book.ts @@ -44,7 +44,6 @@ bookRouter.get("/availability", async (c) => { const serviceId = c.req.query("serviceId"); const dateStr = c.req.query("date"); const petSizeCategory = c.req.query("petSizeCategory") ?? undefined; - const petCoatType = c.req.query("petCoatType") ?? undefined; if (!serviceId || !dateStr) { return c.json({ error: "serviceId and date are required" }, 400); diff --git a/apps/e2e/playwright.config.ts b/apps/e2e/playwright.config.ts index e0970b4..459e3e6 100644 --- a/apps/e2e/playwright.config.ts +++ b/apps/e2e/playwright.config.ts @@ -19,7 +19,7 @@ export default defineConfig({ reporter: process.env.CI ? "github" : "list", use: { - baseURL: "http://localhost:8080", + baseURL: process.env.PLAYWRIGHT_BASE_URL ?? "http://localhost:8080", trace: "on-first-retry", screenshot: "only-on-failure", serviceWorkers: "block", diff --git a/apps/web/src/pages/Book.tsx b/apps/web/src/pages/Book.tsx index 119d2de..885eb2b 100644 --- a/apps/web/src/pages/Book.tsx +++ b/apps/web/src/pages/Book.tsx @@ -515,7 +515,7 @@ export function BookPage() { - +
@@ -568,7 +568,7 @@ export function BookPage() {
Service
{selectedService.name}
-
{fmtPrice(selectedService.basePriceCents)} · {fmtDuration(selectedService.durationMinutes + ((form.petSizeCategory === "large" || form.petSizeCategory === "x-large") ? (selectedService.defaultBufferMinutes ?? 0) : 0))}
+
{fmtPrice(selectedService.basePriceCents)} · {fmtDuration(selectedService.durationMinutes + ((form.petSizeCategory === "large" || form.petSizeCategory === "xlarge") ? (selectedService.defaultBufferMinutes ?? 0) : 0))}
Date & Time