mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-10 19:07:02 +01:00
Add MIGRATION.md documenting the sqlite_crdt -> crdt_sync move
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019KwUCPESvE5CjCtmUFz8xQ
This commit is contained in:
parent
253088c4ed
commit
80e86157ee
44
MIGRATION.md
Normal file
44
MIGRATION.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Migration: `sqlite_crdt` → shared `crdt_sync`
|
||||
|
||||
todo's note storage and sync were moved off `sqlite_crdt` onto the shared
|
||||
[`crdt_sync`](https://github.com/kuhyx/utils/tree/main/crdt_sync_dart) library
|
||||
(pinned tag `crdt_sync_dart-v0.3.0`), so every companion app now syncs through
|
||||
one library.
|
||||
|
||||
## What changed
|
||||
|
||||
- **Storage:** `NoteRepository` is backed by `crdt_sync`'s `LogStore` (a
|
||||
`Log = Map<String, Record>` persisted as JSON). Each `Note` is stored *as* a
|
||||
`Record` (per-field last-writer-wins + a sticky tombstone), so the on-disk
|
||||
log **is** the sync wire format — no separate adapter. Filtering/sorting run
|
||||
in Dart over the in-memory log.
|
||||
- **Sync:** `SyncService` pushes each device's `Log` to
|
||||
`todo-sync/notes/<nodeId>.json` in `kuhyx/syncs` (new dir; the old
|
||||
`changesets/` format is incompatible, so it's a clean cutover). It uses
|
||||
`crdt_sync`'s `GitHubClient` + `logToJson`/`logFromJson`.
|
||||
- **Client:** todo's local `lib/sync/github_client.dart` was deleted; it now
|
||||
uses `crdt_sync`'s `GitHubClient` (which gained `canAccessRepo()` +
|
||||
`deleteFile()` in v0.3.0). `putFileText` self-resolves the file sha, so the
|
||||
old SHA-tracking is gone.
|
||||
|
||||
## The one-time on-device migration
|
||||
|
||||
`NoteRepository.open()` migrates a pre-existing `sqlite_crdt` DB into the log on
|
||||
first launch, guarded by a persisted `crdt.migratedFromSqlite` flag. Verified
|
||||
on-device: a real 27-note backlog (+5 tombstones) migrated intact.
|
||||
|
||||
`sqlite_crdt` is **retained as a dependency** only to read that legacy DB during
|
||||
migration — the old `todo.db` is left untouched as a safety net. Remove the dep
|
||||
in a later cleanup once every device is known-migrated.
|
||||
|
||||
## Surprises / non-obvious decisions
|
||||
|
||||
- **Seed HLCs from each note's `updatedAt`, not "now".** Two devices migrate
|
||||
independently; stamping migration-time "now" would let per-field LWW resolve
|
||||
a pre-cutover edit arbitrarily. Seeding from `updatedAt` keeps
|
||||
last-real-edit-wins across the cutover.
|
||||
- **Reuse the legacy `sqlite_crdt` node id** (persisted in prefs) so a device
|
||||
keeps its `devices/<id>` identity and devices still converge.
|
||||
- **`watchNotes`/`watchCount` seed in `onListen`**, not lazily in an `async*`
|
||||
body — otherwise a write between `listen()` and the first generator tick
|
||||
swallows the initial snapshot.
|
||||
Loading…
Reference in New Issue
Block a user