feat(#370): Calendar-Integration Read — ICS-Subscriptions + Day-View #371

Merged
admin-mrrm merged 1 commit from feat/370-calendar-read into main 2026-05-20 23:13:26 +02:00
Owner

Summary

  • Calendar-Subscriptions als ICS-URL-Abos (auth-frei, lesend)
  • CalendarSyncService.syncOne/syncAll fetcht ICS, parsed VEVENTs, upserted nach (subscriptionId, uid)
  • Hand-rolled ICS-Parser fuer VEVENTs (UID/DTSTART/DTEND/SUMMARY/LOCATION) — kein RRULE, kein TZID-Handling fuer v1
  • CRUD-Endpoints /calendar/subscriptions, Sync via POST /calendar/subscriptions/:id/sync
  • GET /calendar/events?from&to liefert Events im Zeitfenster
  • Day-View-Integration: GET /planner/today enthaelt jetzt events: DayPlanEvent[] neben items: DayPlanItem[]
  • Cron via CALENDAR_SYNC_CRON (Default */15 * * * *), abschaltbar via CALENDAR_SYNC_DISABLED

Phase 6 von Epic #360

  • Phase 1 (Schema): #361
  • Phase 2 (Tracking): #363
  • Phase 3 (Mail): #178
  • Phase 4 (Habits): #366
  • Phase 5 (Planner v0): #368
  • Phase 6 (Calendar Read): #370 ← hier
  • Phase 7 (Planner v1): blockiert durch diese Phase

Test plan

  • Unit-Tests parseIcs (10): UTC/all-day/CRLF/Line-Folding/Escape/Skip
  • Unit-Tests CalendarSyncService (6): syncOne happy/missing/empty, lastSyncAt, syncAll Aggregation + Failure-Tolerance
  • Unit-Tests CalendarService (4): eventsForRange, Subscription-CRUD
  • Integration-Tests (6): Subscription anlegen, Sync, Idempotenz, GET /calendar/events, Day-View mit events, DELETE cascadet
  • pnpm typecheck clean
  • pnpm lint clean
  • 412 Unit-Tests + 79 Integration-Tests gruen

Out of scope (folgt)

  • OAuth-Flows (Outlook/Google)
  • RRULE-Expansion (Recurring Events)
  • TZID-Aufloesung (alle Zeiten als UTC behandelt)
  • Bidirektionales Schreiben

Closes #370

🤖 Generated with Claude Code

## Summary - Calendar-Subscriptions als ICS-URL-Abos (auth-frei, lesend) - `CalendarSyncService.syncOne/syncAll` fetcht ICS, parsed VEVENTs, upserted nach `(subscriptionId, uid)` - Hand-rolled ICS-Parser fuer VEVENTs (UID/DTSTART/DTEND/SUMMARY/LOCATION) — kein RRULE, kein TZID-Handling fuer v1 - CRUD-Endpoints `/calendar/subscriptions`, Sync via `POST /calendar/subscriptions/:id/sync` - `GET /calendar/events?from&to` liefert Events im Zeitfenster - **Day-View-Integration:** `GET /planner/today` enthaelt jetzt `events: DayPlanEvent[]` neben `items: DayPlanItem[]` - Cron via `CALENDAR_SYNC_CRON` (Default `*/15 * * * *`), abschaltbar via `CALENDAR_SYNC_DISABLED` ## Phase 6 von Epic #360 - Phase 1 (Schema): #361 ✅ - Phase 2 (Tracking): #363 ✅ - Phase 3 (Mail): #178 ✅ - Phase 4 (Habits): #366 ✅ - Phase 5 (Planner v0): #368 ✅ - **Phase 6 (Calendar Read): #370 ← hier** - Phase 7 (Planner v1): blockiert durch diese Phase ## Test plan - [x] Unit-Tests `parseIcs` (10): UTC/all-day/CRLF/Line-Folding/Escape/Skip - [x] Unit-Tests `CalendarSyncService` (6): syncOne happy/missing/empty, lastSyncAt, syncAll Aggregation + Failure-Tolerance - [x] Unit-Tests `CalendarService` (4): eventsForRange, Subscription-CRUD - [x] Integration-Tests (6): Subscription anlegen, Sync, Idempotenz, GET /calendar/events, Day-View mit events, DELETE cascadet - [x] `pnpm typecheck` clean - [x] `pnpm lint` clean - [x] 412 Unit-Tests + 79 Integration-Tests gruen ## Out of scope (folgt) - OAuth-Flows (Outlook/Google) - RRULE-Expansion (Recurring Events) - TZID-Aufloesung (alle Zeiten als UTC behandelt) - Bidirektionales Schreiben Closes #370 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(#370): Calendar-Integration Read - ICS-Subscriptions + Day-View (Phase 6 von #360)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
46d5d609b1
Externe Kalender als ICS-URL-Subscriptions abonnieren; CalendarSyncService
fetcht periodisch, parsed VEVENTs (hand-rolled ICS-Parser ohne externe Lib),
upserted nach (subscriptionId, uid). GET /calendar/events?from&to liefert
Events im Zeitfenster, GET /planner/today integriert Events neben den
Candidate-Items in den Day-View.

Cron via CALENDAR_SYNC_CRON (Default */15 min), abschaltbar via
CALENDAR_SYNC_DISABLED. CRUD-Endpoints fuer Subscriptions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
admin-mrrm/mrrmlabapp!371
No description provided.