feat: add CalDAV synchronization with automatic sync

- Add CaldavService with tsdav/ical.js for CalDAV server communication
- Add CaldavController, CaldavRepository, and caldav routes
- Add client-side CaldavConfigService with sync(), config CRUD
- Add CalDAV settings UI with config load/save in settings screen
- Sync on login, auto-login (AuthGuard), periodic timer (calendar), and sync button
- Push single events to CalDAV on server-side create/update/delete
- Push all events to CalDAV after chat event confirmation
- Refactor ChatService to use EventService instead of direct EventRepository
- Rename CalDav/calDav to Caldav/caldav for consistent naming
- Add Radicale Docker setup for local CalDAV testing
- Update PlantUML diagrams and CLAUDE.md with CalDAV architecture
This commit is contained in:
2026-02-08 19:24:59 +01:00
parent 81221d8b70
commit 325246826a
44 changed files with 7074 additions and 126 deletions

View File

@@ -8,13 +8,17 @@ import {
RecurringDeleteMode,
} from "@calchat/shared";
import { ChatService } from "../services";
import { CaldavService } from "../services/CaldavService";
import { createLogger } from "../logging";
import { AuthenticatedRequest } from "./AuthMiddleware";
const log = createLogger("ChatController");
export class ChatController {
constructor(private chatService: ChatService) {}
constructor(
private chatService: ChatService,
private caldavService: CaldavService,
) {}
async sendMessage(req: AuthenticatedRequest, res: Response): Promise<void> {
try {
@@ -68,6 +72,16 @@ export class ChatController {
deleteMode,
occurrenceDate,
);
// Sync confirmed event to CalDAV
try {
if (await this.caldavService.getConfig(userId)) {
await this.caldavService.pushAll(userId);
}
} catch (error) {
log.error({ error, userId }, "CalDAV push after confirm failed");
}
res.json(response);
} catch (error) {
log.error(