mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
feat(storygraph): add StoryGraph sync integration (#568)
* feat(storygraph): add StoryGraph sync integration Sync reading status and progress from BookOrbit to StoryGraph using session-cookie authentication. Includes book matching with manual rematch and edition selection, per-user sync toggles, a throttled request queue, a storygraph_sync permission, and a StoryGraph settings page. Closes #274 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vi6e8ZJRAGMmRSmSj9sWXR * fix(storygraph): address automated review findings - clear stale cookie validation badge when inputs change - reject saves with only one cookie value instead of silently dropping it - handle linked-books load failures with a retryable error state so post-action reloads cannot misattribute failures to the action - add a 30s request timeout so a hung StoryGraph response cannot stall a user's sync queue indefinitely - reserve throttle slots synchronously so concurrent requests serialize - reject empty cookie strings that would overwrite stored credentials - report the retry response status when the rereading fallback fails - add component specs for the connection card and linked books, plus regression tests for the throttle, settings, and retry-status fixes * test(storygraph): fully restore setTimeout spies between queue tests * feat(storygraph): add sync-scope option Adds the book sync scope selector (all eligible books vs selected books only) and the per-book StoryGraph sync control on the book details page, mirroring the Hardcover integration's controls. All books with a syncable status are now eligible — the previous connected-at cutoff that skipped books finished before connecting is removed in favor of explicit scope and per-book selection. * fix(storygraph): stream live sync progress and surface failed books The manual sync progress stream emitted the same mutated status object, so distinctUntilChanged dropped every update after the first and the bar never moved. Progress snapshots are now immutable and track processed books (synced + skipped + failed), so the bar advances for every book. Adds live synced/skipped/failed counters, a persistent last-run summary from a terminal completed/cancelled event, and a failed-books list under Manual sync backed by GET /storygraph/sync/failures. Details-page sync state now refetches when the global sync scope changes. (cherry picked from commit 075eeaa0c8678d4ebbba5dcce7aa15df42d64f51) * feat(storygraph): show distinguishing identifiers in the editions list Edition rows previously showed only format, pages, and language, making identical-looking editions impossible to tell apart. The editions parser now also scrapes ISBN, publisher, publication date, and cover image when present, and each row shows the edition title, those identifiers, a cover thumbnail, and the StoryGraph edition id linking to the edition page for verification before switching. (cherry picked from commit 09ec111613e9be149b556f64eb242cd3d82b296c) * fix(storygraph): auto-refresh linked books after sync and add unmatched hint The Linked books list only loaded on mount, so a book linked during a manual sync run stayed on 'Not linked yet' until a manual page refresh. It now silently reloads when a run completes (no spinner flash, keeps expanded rows), guarded by a request id so overlapping reloads can't resolve out of order. Books StoryGraph couldn't match automatically now show a short hint pointing at 'Try auto-match' or pasting the StoryGraph URL. (cherry picked from commit 1d0cfa1e06f3e211258620f7ad5e61373df7a310) * feat(storygraph): compact edition link and wrap identifiers on mobile The editions list showed the raw StoryGraph edition UUID as a long monospace hyperlink, which was hard to read and cluttered the row. Replace it with a small icon-only 'Open on StoryGraph' button (aria-labelled) next to 'Use this', and let the publisher/date/ISBN line wrap instead of truncating so the ISBN is no longer cut off on narrow/mobile screens. (cherry picked from commit cdf4d64063534adeea9daafad11cd58a0cbc9a00) * fix(storygraph): re-sync books re-added after being marked unread, clarify labels A book synced while 'read' then marked 'unread' left its synced markers in place, so re-marking it read compared against a stale lastSyncedStatus and was silently skipped (shown as Linked but never re-pushed) until 'Try auto-match'. On the unread transition the synced markers are now cleared while keeping the match, so re-adding the book re-syncs. Also present match methods with real casing (ISBN/Title/Cached/Manual) and clarify that the manual-link field takes a StoryGraph URL or book ID (the code after /books/), not an ISBN. (cherry picked from commit 771e7e4fe793afbc30800717ae1c017ca307e5e1) * refactor(storygraph): compare skippedBooks explicitly in sync-status dedup The active-sync stream's equality check omitted skippedBooks, relying on processedBooks (synced+skipped+failed) to capture skip-only changes. That is correct but non-obvious; comparing every counter explicitly makes the intent clear. No behavior change. (cherry picked from commit f267088939f0d2493caadab8eb90f24ab4b28c0b) * fix(storygraph): encode manually-entered book id in the lookup path The manual-link id can be pasted directly, so a stray ?, #, or / would change which /books/ URL is requested. Encode it before interpolating; a bad id now 404s cleanly instead of being stored. * style(storygraph): fix prettier formatting and remove em dashes The CI Lint (Client) job runs prettier --check, which flagged StorygraphLinkedBooks.vue and StorygraphSyncProgress.vue. Reflow both to prettier style and replace em dashes in UI strings and comments with regular punctuation per project convention. * fix(storygraph): harden sync access and batching --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
This commit is contained in:
@@ -431,6 +431,11 @@ describe('Authorization matrix (e2e)', () => {
|
||||
path: '/readwise/settings',
|
||||
token: 'allPerms',
|
||||
},
|
||||
[Permission.StorygraphSync]: {
|
||||
method: 'GET',
|
||||
path: '/storygraph/settings',
|
||||
token: 'allPerms',
|
||||
},
|
||||
[Permission.DemoRestricted]: {
|
||||
method: 'GET',
|
||||
path: '/notifications',
|
||||
|
||||
Reference in New Issue
Block a user