feat(offline): tier 2 phase 1 — Drift cache + read-through for notes
First slice of the tier 2 offline mode work tracked in Fable #147. Notes are the only domain wired so far; this PR establishes the shape and proves the round-trip end-to-end before extending to tasks / projects / events / etc. in phase 2. Local store - Adds drift ^2.20.0 + sqlite3_flutter_libs ^0.5.24 + path ^1.9.0 runtime deps and drift_dev / build_runner dev deps. - New lib/data/local/database.dart: FabledDatabase with CachedNotes (mirroring the Note model 1:1; tags stored as JSON-encoded text) and SyncMetadata (per-domain last_synced_at). Database file lives at $appDocs/fabled_cache.sqlite; opened lazily in a background isolate. - fabledDatabaseProvider on the existing api_client_provider; closes the DB when the ProviderScope disposes. Repository pattern - NotesRepository now takes (NotesApi, FabledDatabase). Reads attempt the network first; on success the response is written to the cache. On NetworkException reads fall back to the cache (rethrowing if it is empty so fresh-install offline still surfaces the network error). - Writes (create/update/delete) hit the server then sync the cache; offline write queueing is phase 3 and explicitly not wired here. - AuthStatus.offline stays owned by AuthNotifier.verify()'s heartbeat; this repo deliberately doesn't poke that state. OfflineBanner - Reads notesRepository.lastSyncedAt(); when present, swaps "Offline — showing cached data." for "Offline — last sync X min ago." A 30s timer refreshes the relative-time string while the banner is mounted. - Falls back to the generic message if no cache exists yet (fresh install offline). Verification - flutter analyze: No issues found Out of scope (later phases per the task body) - Tasks / projects / milestones / events / conversation list / journal day caching (phase 2 — same wrapper pattern, repeated) - Generic write queue with conflict resolution on updated_at (phase 3) - Read-only UI indicators on screens that depend on cached data (phase 4) - Full offline chat (out of scope; needs a local model) - RAG / search over cached content (out of scope) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+145
-1
@@ -57,6 +57,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
sha256: a156715e7cd728130c592f30552575908aae5b100005fbc1f0fb16b3c03a3d10
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.6"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.1"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "22fdcc3cfeb9d974d7408718c4be15ec5e9b1b350088f3a6c88f154e74dd700d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.14.1"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: "0730c18c770d05636a8f945c32a4d7d81cb6e0f0148c8db4ad12e7748f7e49af"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.12.5"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -65,6 +113,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -153,6 +209,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "29f7ecc274a86d32920b1d9cfc7502fa87220da41ec60b55f329559d5732e2b2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.7"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -177,6 +241,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
drift:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: drift
|
||||
sha256: "055c249d1f91be5a47fe447f88afc24c4ca6f4cd6c5ed66767b4797d48acc2e5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.32.1"
|
||||
drift_dev:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: drift_dev
|
||||
sha256: "88a9de3af8571518148a6d8a513b57779fd1e60a026d3ab8a481a878fba01d91"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.32.1"
|
||||
equatable:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -368,6 +448,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.2"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
hooks:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -657,7 +745,7 @@ packages:
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
@@ -808,6 +896,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
recase:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: recase
|
||||
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
record:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -989,6 +1093,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
sha256: ec37cc0e6694374cbef59ed79685572c870a54ede6fa30a3e420feb3adffea02
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1013,6 +1125,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.2"
|
||||
sqlite3:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqlite3
|
||||
sha256: "56da3e13ed7d28a66f930aa2b2b29db6736a233f08283326e96321dd812030f5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
sqlite3_flutter_libs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3_flutter_libs
|
||||
sha256: eeb9e3a45207649076b808f8a5a74d68770d0b7f26ccef6d5f43106eee5375ad
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.42"
|
||||
sqlparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqlparser
|
||||
sha256: ab2b467425f1d4f3acfa5fd11a08226f7d6c26ff102c06be1807e1dff34e050b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.44.3"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1037,6 +1173,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user