From 0c8f897e46b28d88d546e83525e0c578afe82501 Mon Sep 17 00:00:00 2001 From: afiqzudinhadi Date: Mon, 3 Aug 2026 15:51:15 +0800 Subject: [PATCH] fix(library): skip book sync on olid search miss (identity-swap guard) --- packages/obsidian/src/library/book.ts | 13 ++++++++++--- tests/library-book.test.ts | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/obsidian/src/library/book.ts b/packages/obsidian/src/library/book.ts index 77f4c9d..93cb79d 100644 --- a/packages/obsidian/src/library/book.ts +++ b/packages/obsidian/src/library/book.ts @@ -77,7 +77,8 @@ export function buildBook(doc: any, prev: Record): BookRecord { /** Carries the legacy goodreads search link forward as a `## Links` entry across every re-render. */ function resolveGoodreadsLink(prev: Record, body: string): string { - const fromBody = /\[Goodreads\]\(([^)]+)\)/.exec(body ?? ''); + const linksMatch = /##\s*Links\s*\n([\s\S]*?)(?=\n##\s|$)/.exec(body ?? ''); + const fromBody = linksMatch ? /\[Goodreads\]\(([^)]+)\)/.exec(linksMatch[1]) : null; if (fromBody) return fromBody[1]; // first-pass skeleton conversion: legacy plain `url` field IS the goodreads link, before // it gets overwritten by the canonical Open Library url @@ -176,8 +177,14 @@ export const bookSpec: MediaTypeSpec = { deps.log(`book open library fetch failed (olid ${olid}): ${String(e)}`); return null; } - const doc = docs.find(d => String(d.key ?? '') === `/works/${olid}`) ?? docs[0]; - if (!doc) return null; + if (docs.length === 0) return null; + const doc = docs.find(d => String(d.key ?? '') === `/works/${olid}`); + if (!doc) { + // stored olid no longer in the search results -- never silently swap to a + // different work's data; leave the note untouched (id fields preserved) + deps.log(`book open library search returned no doc matching olid ${olid} (title "${query}")`); + return null; + } const record = buildBook(doc, fm); const goodreadsUrl = resolveGoodreadsLink(fm, ctx.body); diff --git a/tests/library-book.test.ts b/tests/library-book.test.ts index 7c63cb3..becdc04 100644 --- a/tests/library-book.test.ts +++ b/tests/library-book.test.ts @@ -215,6 +215,13 @@ describe('bookSpec.sync — open library enrich', () => { expect(result).toBeNull(); }); + test('olid search miss (results present, none match stored olid) -> null, no identity swap, logged', async () => { + const deps = makeDeps({ http: async () => ({ docs: [{ key: '/works/OL999999W', title: '1984', author_name: ['Someone Else'] }] }) }); + const result = await bookSpec.sync(ctxFor({ olid: 'OL1168083W', title: '1984' }), deps); + expect(result).toBeNull(); + expect(deps.logCalls.some(m => m.includes('OL1168083W'))).toBe(true); + }); + test('successful enrich -> canonical fm + flipped always false', async () => { const deps = makeDeps({ http: async () => olFixture }); const fm = { olid: 'OL1168083W', title: '1984', read_status: 'Read', rating: '5', rating_stars: '⭐️⭐️⭐️⭐️⭐️' };