Wikilink index, backlinks API, and phantom-link resolution #47
Labels
No Label
area:auth
area:docs
area:export
area:ops
area:storage
area:supply-chain
auth
backend
blocked
collab
deployment
docs
effort:L
effort:M
effort:S
frontend
plugins
qa
vs-nfd
vs-nfd:blocker
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stwaidele/dorfteich#47
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Backlinks need a server-side index maintained on every content change (data-model.md
page_links).Scope
Extend the content-derivation pipeline (#35) to extract wikilinks into
page_links(targets resolved by slug within the pond; unresolved targets stored as phantom rows withtarget_slug); endpoints:GET /pages/:id/backlinks(pages linking here, permission-filtered),GET /ponds/:id/phantom-links(aggregated missing targets); on page create/rename, resolve/re-point matching phantom rows.Acceptance criteria
Technical notes
page_links), realtime-collaboration.md (derivation hook).Dependencies
Depends on #35, #46.
Size: ~1 day
Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add
deanden), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.Implemented in
14e69b3(Claude Opus 4.8). Pipeline green (CI incl. all e2e packs; CD deploy Test → smoke → promote Int).Live-verified on Test:
GET /ponds/:id/phantom-links→ 200[]andGET /pages/:id/backlinks→ 200[]— thepage_linksindex and its queries run against the migrated stage DB. Index writing, resolution, and permission filtering are covered by db tests (collab + api) and exercised end to end by the #48 e2e (a link created in the editor shows up as a backlink).Acceptance criteria
page_linksfor the source in the same transaction as the content cache (collab db test).to_page_id, so a later rename of the target keeps them connected; renaming to a phantom slug resolves those rows.Notes
PageLink(from_page_id, to_page_id?, target_slug), unique per (from, slug); cascade on source purge, set-null on target purge.deriveContentFromDocnow also returnswikilinkSlugs(sharedextractWikilinkSlugs); one index row per distinct slug, resolved to a same-pond page or null (phantom).unnest(...) AS slugcollided withpages.slug("column reference slug is ambiguous") — the unnest column is aliased distinctly.Next M4 issue: #48 (backlinks panel and phantom-pages view) — already implemented on top of this.