Skip to content

feat: make OnTime fully local-only - #580

Merged
jjoonleo merged 6 commits into
mainfrom
feature/offline-only-ios-release
Aug 28, 2026
Merged

feat: make OnTime fully local-only#580
jjoonleo merged 6 commits into
mainfrom
feature/offline-only-ios-release

Conversation

@jjoonleo

@jjoonleo jjoonleo commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • remove the product server boundary, Firebase, remote authentication, push registration, and analytics from Android/iOS
  • replace remote repositories with encrypted Drift-backed local persistence and a single installation-scoped Local Profile
  • add password-encrypted portable backups, verified atomic restore, full local reset, and recovery mode
  • reconcile alarms and notifications entirely from local durable data, including private notification defaults and platform-capacity scheduling
  • persist named time zones and explicit DST-overlap choices
  • publish the local-only domain decisions in CONTEXT.md and ADR 0011-0035
  • prepare iOS release candidate 1.1.0 (56) and update release documentation

Lifecycle and migration

This is an intentional one-way cutover. Existing remote credentials, caches, legacy local rows, device delivery records, and active sessions are discarded before onboarding. There is no server import path. Active local data is encrypted with a device-bound key. Backup restore authenticates and previews the portable backup before replacing active data atomically, then rebuilds delivery registrations.

Onboarding now preserves immutable preparation-step state while reordering, retains existing durations, and persists the exact spare time shown and edited in the UI. The settings surface uses a Material paint boundary so ListTile ink and backgrounds remain visible under Flutter 3.44.

Persistence and delivery safety

  • SQLCipher is the only native SQLite runtime; the conflicting plain SQLite plugin is no longer registered transitively.
  • Web development uses Drift WASM directly and remains local to browser storage.
  • Alarm reconciliation is idempotent by schedule fingerprint and local registry replacement. Existing registrations are canceled before changed records are re-armed.
  • Restore validates the encrypted container before an atomic replacement and then rebuilds alarm state from the restored database.

Validation

  • dart run build_runner build -d — passed; generated Dart policy aligned
  • flutter analyze — no issues
  • flutter test --coverage --concurrency=1 — 550 passed
  • coverage — 82.39% (8336/10118), required 80%
  • dart run tool/check_local_only_boundary.dart — passed
  • root flutter build web --release — passed
  • Widgetbook generator and flutter build web --release — passed with Flutter 3.44-compatible tooling
  • iOS plist/entitlements lint — passed
  • Android manifest/backup XML lint — passed
  • git diff --check — passed

Generated and platform files

Dependency changes update the tracked native plugin registrants and lockfiles. Generated Dart outputs remain ignored and are not committed. The iOS Podfile is checked in so archive builds can resolve the remaining local-only plugins.

Out of scope

  • server-side migration or data import
  • automatic/cloud backup
  • production App Store review approval; the signed candidate is built and uploaded after merge
  • Firebase Widgetbook preview hosting remains development-only and is not part of the Android/iOS product runtime

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 1639400):

https://on-time-front-widgetbook--pr-580-vvryaypl.web.app

(expires Mon, 31 Aug 2026 17:59:10 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 21ecd99 into main Aug 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant