feat: org-scoped appointments backend, wire appointments page

Add the appointments table, validation, service and CRUD routes
(/api/appointments, RBAC-gated) and the matching frontend data module.
The appointments page now loads and persists real data; KPIs are computed
from it and the schedule/calendar anchor to the real current date.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-07 19:33:37 +03:00
parent 128ce36df2
commit dec04ec506
14 changed files with 2004 additions and 142 deletions
+20
View File
@@ -0,0 +1,20 @@
import { z } from "zod";
// Payload accepted by POST/PUT /api/appointments. Mirrors the frontend
// `NewAppointment` shape; `status` defaults to "confirmed" on create.
export const appointmentInputSchema = z.object({
fileNumber: z.string().trim().default(""),
name: z.string().trim().min(1, "Patient name is required.").max(200),
initials: z.string().trim().min(1).max(4),
date: z
.string()
.regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD."),
time: z.string().regex(/^\d{2}:\d{2}$/, "Time must be HH:mm."),
type: z.string().trim().min(1, "Type is required.").max(120),
provider: z.string().trim().min(1, "Provider is required.").max(200),
status: z
.enum(["confirmed", "checked-in", "completed", "cancelled"])
.default("confirmed"),
});
export type AppointmentInput = z.infer<typeof appointmentInputSchema>;