feat: recurring appointments with cascading change propagation (#28)
* feat: recurring appointments with cascading change propagation Implements GitHub issue #9 — recurring appointment scheduling with configurable frequency and cascade edit/cancel options. Changes: - DB: add `recurring_series` table (frequency_weeks) and series_id / series_index columns on appointments (migration 0003) - API POST /appointments: accepts optional `recurrence` object (frequencyWeeks + count) that creates a full series in one transaction - API PATCH /appointments/🆔 new `cascadeMode` field (this_only | this_and_future | all) applies time-delta shifts and field updates across the series - API DELETE /appointments/🆔 new `?cascade=` query param cancels this_only / this_and_future / all series members - Frontend: booking form gains a "Recurring appointment" checkbox with frequency and count pickers; calendar chips show a ↻ recurring label; detail modal shows "Recurring series" badge and a cascade-delete radio picker for series appointments Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix: resolve TypeScript errors in recurring appointments route Guard against possibly-undefined results from Drizzle .returning() destructuring — use indexed access + explicit null checks instead of array destructuring for the recurring_series insert, and add an early throw when the series or first appointment row is missing. Co-Authored-By: Paperclip <noreply@paperclip.ing> --------- Co-authored-by: Groom Book CTO <cto@groombook.app> Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit was merged in pull request #28.
This commit is contained in:
committed by
GitHub
parent
e524099214
commit
e7cf185d8c
@@ -54,6 +54,12 @@ export interface Staff {
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface RecurringSeries {
|
||||
id: string;
|
||||
frequencyWeeks: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface Appointment {
|
||||
id: string;
|
||||
clientId: string;
|
||||
@@ -65,6 +71,8 @@ export interface Appointment {
|
||||
endTime: string;
|
||||
notes: string | null;
|
||||
priceCents: number | null;
|
||||
seriesId: string | null;
|
||||
seriesIndex: number | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user