From e4f1f0fb42d0c4c84c8d051813b3f9872b2f4bb2 Mon Sep 17 00:00:00 2001 From: Eoic Date: Sat, 5 Sep 2026 23:15:48 +0300 Subject: [PATCH 1/4] Integrate complete PowerSync library synchronization --- POWERSYNC_LIBRARY_SYNC.md | 59 +++++++++++++++++++++++++++++++++++++++ client | 2 +- server | 2 +- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 POWERSYNC_LIBRARY_SYNC.md diff --git a/POWERSYNC_LIBRARY_SYNC.md b/POWERSYNC_LIBRARY_SYNC.md new file mode 100644 index 0000000..c257c72 --- /dev/null +++ b/POWERSYNC_LIBRARY_SYNC.md @@ -0,0 +1,59 @@ +# PowerSync library integration + +Implemented on `feature/powersync-library-sync` in this workspace and its `client` +and `server` submodules. + +Books, shelves, topics (tags), notes, annotations, and book memberships now use +persistent repositories backed by PowerSync. UI saves await local transactions; +reactive library views follow downloaded changes. Guest storage remains local, +and account/server changes invalidate previous repository handles. Existing media +transfer behavior remains in place; device paths and temporary covers are not +uploaded as library metadata. + +The server validates owned references, applies mixed-table uploads atomically, +and merges supplied fields in server acceptance order. Durable entity deletion +records prevent stale offline writes from restoring deleted data. Book deletion +removes dependent records and follows the existing media cleanup path. Shelf +deletion removes memberships and moves immediate child shelves to the root. + +Migration `dcd3b384e6a4` adds the new tables and independently editable book fields. +It preserves the legacy metadata envelope. Client schema expansion preserves +existing databases and queued uploads; legacy normalization retains explicit nulls +and leaves unsupported historical values in their original envelope. + +## Verification + +- Full backend suite: **282 passed, 2 skipped**. +- Full Flutter suite: **1,057 passed, 10 skipped**. Subsequent shelf-icon and + migration regression checks: **12 passed**. +- Ruff checks and changed-file formatting passed; mypy passed for the changed + server implementation and migration. +- Flutter analysis: **no issues**. Release web build passed with icon tree shaking. +- Additive migration upgrade/downgrade and metadata backfill preservation were + verified against a disposable database. +- Live integration passed using two independent PowerSync clients on one + disposable account and another client on a separate account. It covered all + synchronized domains, offline edits and queued writes across restart, + independent-field merging, same-field server-order resolution, null clearing, + membership removal, and deletion against stale offline writes. Disposable + library data was removed and the test accounts disabled afterward. +- The local migration, replication grants/publication, and expanded PowerSync + configuration were applied. Replication checkpoints advanced after restart; + no configuration or replication errors appeared in the checked logs. + +The live test exercises actual native PowerSync databases, HTTP uploads, and +downloads against the local stack. The browser client was release-built; a manual +browser UI session and a live Google OAuth consent flow were not automated. + +## Rollout + +See [the server sync runbook](server/docs/powersync-sandbox.md) for commands and +validation. Deploy the migration and server upload support first, refresh the +publication, activate the expanded PowerSync configuration, verify a checkpoint, +then update/restart clients. No key regeneration, dependency upgrades, or database +reset is required. The client now directly declares `sqlite_async`, already +present at the same locked version as a transitive dependency. + +Standalone series, bookmarks, reading sessions/goals, guest import, conflict UI, +and expanded media transfer remain outside this change. Previously memory-only +non-book data is not automatically assigned to an account. diff --git a/client b/client index a8d04d1..381c6b3 160000 --- a/client +++ b/client @@ -1 +1 @@ -Subproject commit a8d04d1045e1b1077fc3fae44b997ce012df7da7 +Subproject commit 381c6b31ffd788275ff27088037f5d4c43c7cd8c diff --git a/server b/server index 4f29d16..10b656a 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 4f29d162624386bbb88de565166eb1ce8c63b78b +Subproject commit 10b656a7baba9de12a8c7303e293b9ecf636fc1f From 3b8ef84a3d033d6be7d4b852fae230448373e0e6 Mon Sep 17 00:00:00 2001 From: Eoic Date: Sun, 6 Sep 2026 00:32:15 +0300 Subject: [PATCH 2/4] Integrate bookmark synchronization and library editing fixes --- POWERSYNC_LIBRARY_SYNC.md | 21 +++++++++++++++------ client | 2 +- server | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/POWERSYNC_LIBRARY_SYNC.md b/POWERSYNC_LIBRARY_SYNC.md index c257c72..3389222 100644 --- a/POWERSYNC_LIBRARY_SYNC.md +++ b/POWERSYNC_LIBRARY_SYNC.md @@ -3,7 +3,7 @@ Implemented on `feature/powersync-library-sync` in this workspace and its `client` and `server` submodules. -Books, shelves, topics (tags), notes, annotations, and book memberships now use +Books, shelves, topics (tags), notes, annotations, bookmarks, and book memberships now use persistent repositories backed by PowerSync. UI saves await local transactions; reactive library views follow downloaded changes. Guest storage remains local, and account/server changes invalidate previous repository handles. Existing media @@ -21,11 +21,20 @@ It preserves the legacy metadata envelope. Client schema expansion preserves existing databases and queued uploads; legacy normalization retains explicit nulls and leaves unsupported historical values in their original envelope. +The September 6 follow-up adds bookmark migration `af0fea8d6317`, including owner +filtering, tombstones, and book-deletion cleanup. Physical-book bookmarks preserve +page, position, chapter, note, color, and creation date. Bookmark forms await +persistence and retain failed saves for retry. + +Annotation actions now open the complete, prefilled **Edit annotation** form, +including highlighted text, page, chapter title, attached note, and color. +Library favorites now persist `is_favorite` on the book instead of changing a +view-only override; synchronized favorite changes update the library views. + ## Verification -- Full backend suite: **282 passed, 2 skipped**. -- Full Flutter suite: **1,057 passed, 10 skipped**. Subsequent shelf-icon and - migration regression checks: **12 passed**. +- Full backend suite: **295 passed, 2 skipped**. +- Full Flutter suite: **1,080 passed, 10 skipped**. - Ruff checks and changed-file formatting passed; mypy passed for the changed server implementation and migration. - Flutter analysis: **no issues**. Release web build passed with icon tree shaking. @@ -35,7 +44,7 @@ and leaves unsupported historical values in their original envelope. disposable account and another client on a separate account. It covered all synchronized domains, offline edits and queued writes across restart, independent-field merging, same-field server-order resolution, null clearing, - membership removal, and deletion against stale offline writes. Disposable + membership removal, physical-book bookmarks, favorites, and deletion against stale offline writes. Disposable library data was removed and the test accounts disabled afterward. - The local migration, replication grants/publication, and expanded PowerSync configuration were applied. Replication checkpoints advanced after restart; @@ -54,6 +63,6 @@ then update/restart clients. No key regeneration, dependency upgrades, or databa reset is required. The client now directly declares `sqlite_async`, already present at the same locked version as a transitive dependency. -Standalone series, bookmarks, reading sessions/goals, guest import, conflict UI, +Standalone series, reading sessions/goals, guest import, conflict UI, and expanded media transfer remain outside this change. Previously memory-only non-book data is not automatically assigned to an account. diff --git a/client b/client index 381c6b3..355f8bf 160000 --- a/client +++ b/client @@ -1 +1 @@ -Subproject commit 381c6b31ffd788275ff27088037f5d4c43c7cd8c +Subproject commit 355f8bff0534f3b73fecbbbb5df5351b4c41947a diff --git a/server b/server index 10b656a..c61455c 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 10b656a7baba9de12a8c7303e293b9ecf636fc1f +Subproject commit c61455c183de1a4f944ba951338228899b265fc5 From a986cbaf5e806ef128c8ec4f500068bc95210bcc Mon Sep 17 00:00:00 2001 From: Eoic Date: Sun, 6 Sep 2026 01:58:45 +0300 Subject: [PATCH 3/4] Remove outdated specs. --- POWERSYNC_LIBRARY_SYNC.md | 68 --------------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 POWERSYNC_LIBRARY_SYNC.md diff --git a/POWERSYNC_LIBRARY_SYNC.md b/POWERSYNC_LIBRARY_SYNC.md deleted file mode 100644 index 3389222..0000000 --- a/POWERSYNC_LIBRARY_SYNC.md +++ /dev/null @@ -1,68 +0,0 @@ -# PowerSync library integration - -Implemented on `feature/powersync-library-sync` in this workspace and its `client` -and `server` submodules. - -Books, shelves, topics (tags), notes, annotations, bookmarks, and book memberships now use -persistent repositories backed by PowerSync. UI saves await local transactions; -reactive library views follow downloaded changes. Guest storage remains local, -and account/server changes invalidate previous repository handles. Existing media -transfer behavior remains in place; device paths and temporary covers are not -uploaded as library metadata. - -The server validates owned references, applies mixed-table uploads atomically, -and merges supplied fields in server acceptance order. Durable entity deletion -records prevent stale offline writes from restoring deleted data. Book deletion -removes dependent records and follows the existing media cleanup path. Shelf -deletion removes memberships and moves immediate child shelves to the root. - -Migration `dcd3b384e6a4` adds the new tables and independently editable book fields. -It preserves the legacy metadata envelope. Client schema expansion preserves -existing databases and queued uploads; legacy normalization retains explicit nulls -and leaves unsupported historical values in their original envelope. - -The September 6 follow-up adds bookmark migration `af0fea8d6317`, including owner -filtering, tombstones, and book-deletion cleanup. Physical-book bookmarks preserve -page, position, chapter, note, color, and creation date. Bookmark forms await -persistence and retain failed saves for retry. - -Annotation actions now open the complete, prefilled **Edit annotation** form, -including highlighted text, page, chapter title, attached note, and color. -Library favorites now persist `is_favorite` on the book instead of changing a -view-only override; synchronized favorite changes update the library views. - -## Verification - -- Full backend suite: **295 passed, 2 skipped**. -- Full Flutter suite: **1,080 passed, 10 skipped**. -- Ruff checks and changed-file formatting passed; mypy passed for the changed - server implementation and migration. -- Flutter analysis: **no issues**. Release web build passed with icon tree shaking. -- Additive migration upgrade/downgrade and metadata backfill preservation were - verified against a disposable database. -- Live integration passed using two independent PowerSync clients on one - disposable account and another client on a separate account. It covered all - synchronized domains, offline edits and queued writes across restart, - independent-field merging, same-field server-order resolution, null clearing, - membership removal, physical-book bookmarks, favorites, and deletion against stale offline writes. Disposable - library data was removed and the test accounts disabled afterward. -- The local migration, replication grants/publication, and expanded PowerSync - configuration were applied. Replication checkpoints advanced after restart; - no configuration or replication errors appeared in the checked logs. - -The live test exercises actual native PowerSync databases, HTTP uploads, and -downloads against the local stack. The browser client was release-built; a manual -browser UI session and a live Google OAuth consent flow were not automated. - -## Rollout - -See [the server sync runbook](server/docs/powersync-sandbox.md) for commands and -validation. Deploy the migration and server upload support first, refresh the -publication, activate the expanded PowerSync configuration, verify a checkpoint, -then update/restart clients. No key regeneration, dependency upgrades, or database -reset is required. The client now directly declares `sqlite_async`, already -present at the same locked version as a transitive dependency. - -Standalone series, reading sessions/goals, guest import, conflict UI, -and expanded media transfer remain outside this change. Previously memory-only -non-book data is not automatically assigned to an account. From f00c3a235636936a97f09da5cd888589f312f06f Mon Sep 17 00:00:00 2001 From: Eoic Date: Sun, 6 Sep 2026 02:00:54 +0300 Subject: [PATCH 4/4] Update client submodule for current library sync branch --- client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client b/client index 355f8bf..45c95d1 160000 --- a/client +++ b/client @@ -1 +1 @@ -Subproject commit 355f8bff0534f3b73fecbbbb5df5351b4c41947a +Subproject commit 45c95d1aa4a3dc0c58515458c24ca62b6b0a7dc0