diff --git a/landing/app/mira/wiki/[pageName]/page.tsx b/landing/app/mira/wiki/[pageName]/page.tsx index 6df40fa..d824508 100644 --- a/landing/app/mira/wiki/[pageName]/page.tsx +++ b/landing/app/mira/wiki/[pageName]/page.tsx @@ -49,6 +49,9 @@ export default function WikiPagePage({ const [paragraphs, setParagraphs] = useState([]); const [triplets, setTriplets] = useState([]); const [entitySet, setEntitySet] = useState>(new Set()); + // Backlinks:所有提到此 entity 的 raw note(V3 wiki_synthesis 在 wiki-page tags 寫 raw:XXX) + // 對應 leo 2026-05-17 #2 反饋:「從這本書的條目應該反向連到那篇筆記去」 + const [backlinkRaws, setBacklinkRaws] = useState([]); const [collapsed, setCollapsed] = useState>({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -117,6 +120,42 @@ export default function WikiPagePage({ } } setEntitySet(eset); + + // Backlinks:找此 entity 的所有 wiki-page (可能多次寫入),提取 raw:XXX tag → fetch raw blocks + if (wikiPage.type === 'wiki-page' && wikiPage.content) { + const sameEntity = allPages.filter((p) => p.content?.trim() === wikiPage.content?.trim()); + const rawIds = new Set(); + for (const wp of sameEntity) { + try { + const tags = JSON.parse(wp.tags_json || '[]') as string[]; + for (const t of tags) { + if (typeof t === 'string' && t.startsWith('raw:')) { + rawIds.add(t.slice(4)); + } + } + } catch { /* skip */ } + } + if (rawIds.size > 0) { + // 一次撈 raw blocks,page_name 是 unique 一次 query 一個 + const rawBlocks: Block[] = []; + await Promise.all( + Array.from(rawIds).map(async (rawId) => { + try { + // KBDB GET /blocks/:id 直接 by id (走 list with block_id filter) + const r = await fetch(`${KBDB_BASE}/blocks/${rawId}`, { headers }); + if (r.ok) { + const data = await r.json(); + const b = data.blocks?.[0] ?? data; + if (b?.id) rawBlocks.push(b as Block); + } + } catch { /* skip */ } + }), + ); + if (!cancelled) { + setBacklinkRaws(rawBlocks.sort((a, b) => b.updated_at - a.updated_at)); + } + } + } } catch (e: any) { if (!cancelled) setError(e?.message ?? 'load failed'); } finally { @@ -207,6 +246,40 @@ export default function WikiPagePage({ )} + {/* Backlinks:提到此 entity 的 raw notes */} + {isWikiPage && backlinkRaws.length > 0 && ( +
+

+ 📎 提到此 entity 的筆記 ({backlinkRaws.length}) +

+ +
+ )} +