A local-first Android app that wakes you for calendar meetings the way an alarm clock wakes you in the morning: full-screen, lock-screen-bypassing, ringing until you dismiss it. Built on Compose Multiplatform with iOS targets compiled from day one. Architectural mandate: never weaken alarm reliability.
Problem
Calendar notifications fail too often: silent on Do Not Disturb, swallowed by Doze, killed by aggressive OEM battery managers, or buried in a notification shade you didn't check. For a remote engineer whose income depends on being on time to a 14:00 meeting learned about at 13:42, 'I didn't see the notification' is not an acceptable outcome.
Approach
Multi-source event ingest into a single local database. Schedule exact alarms with the OS-level alarm primitives: the same ones that make your morning alarm reliable. No backend. Crashlytics for stack traces only, with PII scrubbing on calendar content.
Sources
- Android's
CalendarContractprovider: zero config if calendars are already synced on the phone - Google Calendar OAuth via AppAuth: for work calendars not exposed to the device
- ICS subscription URLs: fallback when OAuth is blocked by org policy
- Manual entry: guaranteed-to-work path for any meeting
Deduped into a single local DB keyed by (iCalUID, calendarId). ContentObserver-debounced refresh on Android calendar changes; cadenced refresh for OAuth + ICS.
Architectural mandates
Never weaken alarm reliability
setExactAndAllowWhileIdle, boot-completed receivers, battery-optimization onboarding, full-screen-intent permission flow, foreground-service-only-when-needed. Any code change that risks alarm reliability (even theoretically) gets blocked.
Never store calendar data outside the device
No backend. No analytics on event content. Crashlytics carries stack traces and device metadata only, with PII scrubbing on. The user's calendar is the user's, full stop.
iOS shared code from day one
:composeApp:commonMain already targets iOS. Platform actuals (AlarmManager, CalendarContract, AppAuth) are stubbed via NotImplementedError("iOS implementation pending: <feature>"). The iOS build never breaks; it just runs the stubs.
Stack
- Kotlin 2.x, Compose Multiplatform + Material 3
- Koin DI (KMP-native), Coroutines + Flow
- Room 3 KMP via KSP, DataStore Preferences (KMP)
- Ktor + Kotlinx Serialization, AppAuth-Android for OAuth
- WorkManager (Android), BGTaskScheduler stub (iOS)
- Kermit logging with PII scrubbing, Firebase Crashlytics (Android only)
Status
Android v1 in active development. PRD frozen at v1.2. iOS code already compiles for both targets; platform actuals follow Android ship.