Skip to content

feat(ui): dual-read/write libraries↔workspaces account-sync key (LIB-6 A5)#158

Merged
eliotlim merged 1 commit into
mainfrom
feat/lib6-sync-key-libraries
Jul 14, 2026
Merged

feat(ui): dual-read/write libraries↔workspaces account-sync key (LIB-6 A5)#158
eliotlim merged 1 commit into
mainfrom
feat/lib6-sync-key-libraries

Conversation

@eliotlim

Copy link
Copy Markdown
Owner

Problem

AccountProvider syncs the page-container roster to the account under the JSON key workspaces. The product-wide rename of that container noun to library (epic LIB) requires the sync key to become libraries. A hard rename would break settings sync during rollout: a new client writing libraries against a not-yet-deployed server (which still reads workspaces) would silently drop the roster, and vice versa. The rename must land with zero data loss across any old/new client-server pairing.

Solution

Dual-read/write back-compat in packages/ui/src/providers/AccountProvider.tsx:

  • Read: libraries ?? workspaces — prefer the new canonical key, fall back to the legacy one so an old server (or old locally-stored blob) still hydrates.
  • Write: emit both libraries and workspaces so an old server that only reads workspaces keeps working, while a new server prefers libraries.

The server half lives in the paired open.book.pub PR (mirrorLibraryKeys copies present→both on GET and PUT).

Non-visual change — sync/persistence only.

Before / After

Before After
Read key workspaces libraries ?? workspaces
Write payload workspaces only libraries and workspaces
New client ↔ old server roster lost interops (still writes workspaces)
New client ↔ new server canonical libraries

Test procedure

  • pnpm --filter @book.dev/ui run typecheck → exit 0 (after build:libs builds the @book.dev/sdk dist that verify builds first; bare typecheck against a stale dist fails identically on untouched main and is unrelated to this change — none of those errors touch AccountProvider).
  • pnpm --filter @book.dev/ui exec vitest run src/providers/__tests__/AccountProvider.test.tsx → 13 pass / 0 fail (covers read-fallback and dual-write both directions).

Operational notes

  • The client half is independently safe against the current production server: it still writes workspaces, so nothing breaks if the account deploy hasn't landed.
  • The account (server) deploy is owner-gated; this PR coordinates with it but does not depend on it to ship safely.
  • Security-reviewed alongside the account PR (Sasha: CLEAR WITH NITS; nits applied on the server side — array-typed guard + post-mirror size cap).

…LIB-6)

The account-sync blob carried the library list under the legacy wire key
`workspaces`; LIB-5 renamed the values to Library[] but missed the key itself.
Dual-write the list under BOTH `libraries` (new canonical) and `workspaces`
(legacy) — always equal — and dual-read incoming blobs as `libraries ??
workspaces` (prefer new). An account server on either side of the rename now
interoperates with no data loss: an old server storing the blob verbatim still
exposes `workspaces` to old clients, and the new server mirrors both keys.

Adds 4 interop tests (new↔new dual-write, new↔old-server fallback read,
prefer-new when both present, old-write round-trip through a mirroring server).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KFk2T9k3p7ghCjdzMfkA5w
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app.book.pub Ready Ready Preview, Comment Jul 14, 2026 1:25am

Request Review

@eliotlim

Copy link
Copy Markdown
Owner Author

Paired server half (open.book.pub): https://github.com/eliotlim/open.book.pub/pull/29 — the two coordinate but each is independently back-compatible.

@eliotlim eliotlim merged commit e7afa31 into main Jul 14, 2026
10 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