feat: add recurring event deletion with three modes

Implement three deletion modes for recurring events:
- single: exclude specific occurrence via EXDATE mechanism
- future: set RRULE UNTIL to stop future occurrences
- all: delete entire event series

Changes include:
- Add exceptionDates field to CalendarEvent model
- Add RecurringDeleteMode type and DeleteRecurringEventDTO
- EventService.deleteRecurring() with mode-based logic using rrule library
- EventController DELETE endpoint accepts mode/occurrenceDate query params
- recurrenceExpander filters out exception dates during expansion
- AI tools support deleteMode and occurrenceDate for proposed deletions
- ChatService.confirmEvent() handles recurring delete modes
- New DeleteEventModal component for unified delete confirmation UI
- Calendar screen integrates modal for both recurring and non-recurring events
This commit is contained in:
2026-01-25 15:19:31 +01:00
parent a42e2a7c1c
commit 2b999d9b0f
35 changed files with 787 additions and 200 deletions

View File

@@ -7,6 +7,7 @@ import {
CreateEventDTO,
UpdateEventDTO,
EventAction,
RecurringDeleteMode,
} from "@calchat/shared";
import { ApiClient } from "./ApiClient";
@@ -16,6 +17,8 @@ interface ConfirmEventRequest {
event?: CreateEventDTO;
eventId?: string;
updates?: UpdateEventDTO;
deleteMode?: RecurringDeleteMode;
occurrenceDate?: string;
}
interface RejectEventRequest {
@@ -35,6 +38,8 @@ export const ChatService = {
event?: CreateEventDTO,
eventId?: string,
updates?: UpdateEventDTO,
deleteMode?: RecurringDeleteMode,
occurrenceDate?: string,
): Promise<ChatResponse> => {
const body: ConfirmEventRequest = {
proposalId,
@@ -42,6 +47,8 @@ export const ChatService = {
event,
eventId,
updates,
deleteMode,
occurrenceDate,
};
return ApiClient.post<ChatResponse>(
`/chat/confirm/${conversationId}/${messageId}`,