feat(db): add wiki-link extraction, resolution, and backlinks #44

Merged
lerko merged 1 commits from feat/entry-linking into main 2026-05-21 17:49:04 +00:00
Owner

Summary

  • Wiki-link extraction: new internal/link package with ExtractLinks() — regex-based [[link text]] parser, pure function, no DB access. Links stay in body text (not extracted like tags).
  • Link resolution: title match first (case-insensitive), body substring fallback, most recent wins ties. Self-references excluded. Unresolved links stored with NULL to_id for future re-resolution.
  • Schema v5: entity_links(from_id, to_id, link_text) junction table. CASCADE on source delete, SET NULL on target delete.
  • Sync on mutation: syncLinks() wired into Create, Update, and Absorb transactions.
  • Backlinks in detail view: entries linking to current entry shown after tags section. Loaded async on detail enter.

Test plan

  • Create entry: nginx proxy trick #ops
  • Create entry: see [[nginx proxy trick]] for config
  • Open first entry in detail → verify backlinks section shows second entry
  • Edit second entry to remove link → verify backlink disappears on reload
  • Create entry with [[nonexistent]] → verify no errors (unresolved link stored)
  • Absorb two entries with links → verify links re-sync on merged body
  • Delete source entry → verify backlink disappears from target
  • All tests pass (go test ./...)
## Summary - **Wiki-link extraction**: new `internal/link` package with `ExtractLinks()` — regex-based `[[link text]]` parser, pure function, no DB access. Links stay in body text (not extracted like tags). - **Link resolution**: title match first (case-insensitive), body substring fallback, most recent wins ties. Self-references excluded. Unresolved links stored with NULL `to_id` for future re-resolution. - **Schema v5**: `entity_links(from_id, to_id, link_text)` junction table. CASCADE on source delete, SET NULL on target delete. - **Sync on mutation**: `syncLinks()` wired into Create, Update, and Absorb transactions. - **Backlinks in detail view**: entries linking to current entry shown after tags section. Loaded async on detail enter. ## Test plan - [x] Create entry: `nginx proxy trick #ops` - [x] Create entry: `see [[nginx proxy trick]] for config` - [x] Open first entry in detail → verify backlinks section shows second entry - [x] Edit second entry to remove link → verify backlink disappears on reload - [x] Create entry with `[[nonexistent]]` → verify no errors (unresolved link stored) - [x] Absorb two entries with links → verify links re-sync on merged body - [x] Delete source entry → verify backlink disappears from target - [x] All tests pass (`go test ./...`)
lerko added 1 commit 2026-05-21 17:40:21 +00:00
[[wiki-links]] in entry bodies are extracted at save time, resolved
to entity IDs (title match first, body substring fallback), and
stored in entity_links junction table. Backlinks surface in TUI
detail view showing entries that link to the current entry.

Schema migration v5 adds entity_links with CASCADE/SET NULL
semantics. Links sync on Create, Update, and Absorb.
lerko merged commit 8426c2fbc1 into main 2026-05-21 17:49:04 +00:00
lerko deleted branch feat/entry-linking 2026-05-21 17:49:04 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lerko/nib-v1#44