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:
7
packages/shared/src/models/CaldavConfig.ts
Normal file
7
packages/shared/src/models/CaldavConfig.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface CaldavConfig {
|
||||
userId: string;
|
||||
serverUrl: string;
|
||||
username: string;
|
||||
password: string;
|
||||
syncIntervalSeconds?: number;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
export interface CalendarEvent {
|
||||
id: string;
|
||||
userId: string;
|
||||
caldavUUID?: string;
|
||||
etag?: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
startTime: Date;
|
||||
@@ -10,9 +12,11 @@ export interface CalendarEvent {
|
||||
exceptionDates?: string[]; // ISO date strings (YYYY-MM-DD) for excluded occurrences
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
caldavSyncStatus?: CaldavSyncStatus;
|
||||
}
|
||||
|
||||
export type RecurringDeleteMode = "single" | "future" | "all";
|
||||
export type CaldavSyncStatus = "synced" | "error";
|
||||
|
||||
export interface DeleteRecurringEventDTO {
|
||||
mode: RecurringDeleteMode;
|
||||
@@ -20,6 +24,8 @@ export interface DeleteRecurringEventDTO {
|
||||
}
|
||||
|
||||
export interface CreateEventDTO {
|
||||
caldavUUID?: string;
|
||||
etag?: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
startTime: Date;
|
||||
@@ -27,9 +33,12 @@ export interface CreateEventDTO {
|
||||
note?: string;
|
||||
recurrenceRule?: string;
|
||||
exceptionDates?: string[]; // For display in proposals
|
||||
caldavSyncStatus?: CaldavSyncStatus;
|
||||
}
|
||||
|
||||
export interface UpdateEventDTO {
|
||||
caldavUUID?: string;
|
||||
etag?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
startTime?: Date;
|
||||
@@ -37,6 +46,7 @@ export interface UpdateEventDTO {
|
||||
note?: string;
|
||||
recurrenceRule?: string;
|
||||
exceptionDates?: string[];
|
||||
caldavSyncStatus?: CaldavSyncStatus;
|
||||
}
|
||||
|
||||
export interface ExpandedEvent extends CalendarEvent {
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from "./User";
|
||||
export * from "./CalendarEvent";
|
||||
export * from "./ChatMessage";
|
||||
export * from "./Constants";
|
||||
export * from "./CaldavConfig";
|
||||
|
||||
@@ -69,3 +69,11 @@ export function formatDateWithWeekdayShort(date: Date): string {
|
||||
month: "2-digit",
|
||||
});
|
||||
}
|
||||
|
||||
// Format date as YYYY-MM-DD for exception date comparison
|
||||
export function formatDateKey(date: Date): string {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user