Replaces the Angular 18 app with Next.js 16 / React 19 / Tailwind 4 / shadcn, the same stack and design system as nachklang-feedback, planned in docs/rewrite-plan.md. - Admin: all calendars in one mobile-friendly list (month groups, calendar chips, Kommend/Vergangen/Alle, search, sort, filters in the URL), an edit sheet for create/edit/duplicate/delete, publish confirmation, and an "Abonnieren" dialog with subscription links for every calendar. - Public landing page: subscribe links from env instead of hardcoded, plus the next public events, server-rendered and revalidated every 5 minutes. - All times handled explicitly as Europe/Berlin; whole-day events stored as 00:00-23:59. Fixes carried over from the Angular app: the move dialog leaking a cancelled calendar change, saves that looked saved when they failed, in-place Date mutation, and duplicated calendar-id mappings. - Same shared-session auth as before (proxy.ts gate, /admin/me, 401 vs 403). - 112 Vitest tests over lib/; docs in docs/ (architecture, features, gotchas, API wish list, deployment). Needs the API branch feature/calendar-ical-escaping-subscriptions deployed first (GET /calendar/events/subscriptions). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.0 KiB
2.0 KiB
API wish list
Changes to the API that would help this app, collected during the rewrite. None of them block it. Done items move to the bottom.
Open
- List the calendars. Ids, slugs and names are hardcoded in
lib/calendars.tsand must be kept in step withcalendarNamesinevents.router.ts. An endpoint would make a new calendar a data change. - All calendars in one request. The admin list makes five parallel requests on every load.
- Restore / history. Every save already writes a row to
event_versions, and delete is aDELETEDversion - so "Wiederherstellen" and a change history are possible without schema changes, only endpoints are missing. The UI's delete dialog says it can't be undone "hier". - Don't return deleted events from the admin feed (or behind a flag). They arrive as rows with
every field
nullexceptstatus, and the client has to know to drop them. - Richer recurrence.
repeatFrequencygoes out asRRULE:FREQ=<value>with no interval, end or count. With those, recurrence could become editable in the form (today only Geburtstage getYEARLY, automatically). - A failed update should not be a 200.
PUT /calendar/events/:idanswers 200{"message": "0 rows were updated"}when nothing was written; the client treats that body as an error. A 404/409 would say it properly. - Explicit time zones. The API relies on the process running in Berlin time for the iCal output
(see the API's
docs/calendar-ical.md). SettingTZexplicitly at start-up, or formatting with an explicit zone, would remove the dependency on the server's configuration. ORGANIZERas a cal-address (ORGANIZER;CN=Name:mailto:…) instead of a bare name.DB_PORTfor every pool. Only the admin pool reads it; calendar, feedback and tickets always use 3306.
Done
- iCal escaping, line folding and CRLF;
text/calendarcontent type (API branchfeature/calendar-ical-escaping-subscriptions, 2026-09-28). GET /calendar/events/subscriptionsfor the "Abonnieren" dialog (same branch).