Now that portal clients are restricted to status:"cancelled" only,
update the PATCH /portal/waitlist/:id tests to send a valid value
so auth and ownership checks are exercised correctly.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Restrict portal PATCH waitlist status to z.literal("cancelled") only
- Appointment notes: field projection + null check from PR #109
- Resolve index.ts conflict: keep both portal and calendar public routes
- Resolve portal.ts conflict: keep min(1) validation for customerNotes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Move client-facing POST/PATCH/DELETE waitlist routes to portalRouter
so impersonation sessions can reach them (were blocked by requireRole guard)
- Fix portalRouter double-mount: remove from auth-protected api block,
register publicly at app.route("/api/portal", ...) instead
- Replace N+1 queries in GET /waitlist with a single JOIN across
clients, pets, and services tables
- Remove dead expiredIds variable in markExpiredEntries; use .some()
instead of computing an array only for its length
- Fix stray indentation in appointments.ts DELETE handler (line 487)
- Update waitlist tests to exercise routes at new /portal/waitlist paths;
add leftJoin and lt to chainable mock
Co-Authored-By: Paperclip <noreply@paperclip.ing>
TypeScript's split()[0] is typed as string | undefined in strict mode.
Using slice(0, 10) is cleaner and avoids the type issue.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
When reading waitlist entries, active entries with preferredDate < today
are marked as expired both in the database and in the response.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add 401 when DELETE /waitlist/:id has no session (auth bypass fix)
- Add auth to PATCH /waitlist/:id (was zero auth)
- Add RBAC guard for /waitlist/* routes
- Fix migration to use proper ENUM type instead of TEXT
- Add unit tests for auth scenarios
Co-Authored-By: Paperclip <noreply@paperclip.ing>