/** * Shapes on the wire and in the app. * * `ApiEvent` is what `GET /calendar/events/:calendar/json` actually returns, * which is looser than the API's own `Event` interface claims: the service maps * raw MariaDB rows straight through (`toEvent` in events.service.ts), so * `wholeDay` arrives as whatever the driver produced for the column (1/0 rather * than true/false is the likely case), and a deleted event's latest version is * a row with only `status` set - every other version column is null. `status` * is missing entirely from the anonymous public listing. * * `CalendarEvent` is the parsed, trustworthy form everything else in the app * works with. Parsing happens once, in `parseApiEvent`. */ export type EventStatus = "PUBLIC" | "PRIVATE" | "DRAFT" | "DELETED"; export interface ApiEvent { eventId: number; calendarId: number; uuid: string; name: string | null; description: string | null; startDateTime: string | null; endDateTime: string | null; createdDate: string | null; lastModifiedDate?: string | null; location: string | null; createdBy?: string | null; lastModifiedBy?: string | null; url: string | null; wholeDay: boolean | number | null; repeatFrequency: string | null; status?: string | null; } export interface CalendarEvent { eventId: number; calendarId: number; uuid: string; name: string; description: string; /** Instants. Wall-clock meaning is always Europe/Berlin, see lib/dates.ts. */ start: Date; end: Date; created: Date | null; lastModified: Date | null; location: string; createdBy: string; lastModifiedBy: string; url: string; wholeDay: boolean; /** "" when the event does not repeat. Sent to iCal verbatim as RRULE:FREQ=… */ repeatFrequency: string; status: EventStatus; } /** * The body of POST /calendar/events, PUT /calendar/events/:id and * PUT /calendar/events/move/:id. * * Every field is required here on purpose. PUT replaces the whole version and * defaults whatever is missing - `repeatFrequency ?? ''`, `status ?? 'PUBLIC'` * (events.router.ts) - so a partial body silently drops a birthday's * recurrence or publishes a draft. */ export interface EventPayload { calendarId: number; name: string; description: string; startDateTime: string; endDateTime: string; location: string; url: string; wholeDay: boolean; repeatFrequency: string; status: EventStatus; } /** GET /admin/me - the signed-in account, shared by all Nachklang apps. */ export interface AdminUser { id: string; email: string; fullName: string; apps: string[]; }