feat([issue-730]): per-session cross-machine resume toggle + reconcile in Story Builder - #869
Merged
Conversation
…e in Story Builder Wire the Story Builder page to the existing POST /:id/sync and POST /:id/reconcile routes (#861). Each session header gains a cross-machine-resume toggle; for synced sessions a Reconcile button re-baselines staleness against this machine's live records. Add a syncDrift signal to the session view so the reconcile action only enables when this machine's records have actually drifted from the session's carried baseline — computed from the live hashes already gathered in getStorySessionView, so no extra reads.
…Steps update reactively
Both reviewers flagged that POST /:id/sync and /:id/reconcile returned
the bare session record, so toggling sync or reconciling — which shift
the staleness baseline and can change which locked steps read as stale —
left the step rail's stale badges showing pre-mutation state until a
reload. The routes now return the same flattened view as GET /:id
({ ...session, staleSteps, syncDrift }) and the client merges all three
fields, no full refetch. Also align the computeSyncDrift JSDoc with its
missing-baseline-counts-as-drift behavior and list it in the lib README.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ships the final slice of #730: the in-page UI for cross-machine resumable Story Builder sessions. The backend (
POST /:id/sync,POST /:id/reconcile) shipped in #861 and the sync wire integration in #866 — this PR wires the Story Builder page to those existing endpoints.POST /:id/sync). Local-only is the default.POST /:id/reconcile) that re-baselines the session's staleness against this machine's live universe/series records. Reconcile is hidden for local-only sessions (the route rejects them) and enabled only when drift exists.syncDriftsignal to the session view so the reconcile button only enables when this machine's records have actually diverged from the session's carriedsyncedHashesbaseline — computed from the live hashes already gathered ingetStorySessionView, so no extra reads. Alwaysfalsefor local-only sessions.apiStoryBuilderwrapperssetStorySessionSync/reconcileStorySession(auto-exported via the services barrel; README row updated). Both mutate local state reactively after the call (no full refetch) and pass{ silent: true }since they own their own toast.Closes #730
Test plan
cd server && npx vitest run lib/storyBuilderIntegrity routes/storyBuilder services/storyBuilder— 111 pass, including newcomputeSyncDriftunit tests, the view'ssyncDriftflag, the/:id/sync+/:id/reconcileroute dispatch (and local-only reconcile → 400 mapping).cd client && npx vitest run src/pages/StoryBuilder.test.jsx— 19 pass, including two new UI tests: toggling sync on reveals the reconcile control reactively, and reconcile enables only on drift and clears it.