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

@@ -35,7 +35,10 @@ if (process.env.NODE_ENV !== "production") {
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS",
);
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-User-Id");
res.header(
"Access-Control-Allow-Headers",
"Content-Type, Authorization, X-User-Id",
);
if (req.method === "OPTIONS") {
res.sendStatus(200);
return;
@@ -54,8 +57,13 @@ const aiProvider = new GPTAdapter();
// Initialize services
const authService = new AuthService(userRepo);
const chatService = new ChatService(chatRepo, eventRepo, aiProvider);
const eventService = new EventService(eventRepo);
const chatService = new ChatService(
chatRepo,
eventRepo,
eventService,
aiProvider,
);
// Initialize controllers
const authController = new AuthController(authService);