Projects BibleWeb Notes Note cross-linking
Done

Note cross-linking

Area: Notes Milestone: v1

Context

Problem: Bible study often reveals connections between passages. When a user has notes on both Genesis 1:1 and John 1:1, they may want to link those notes together to represent the thematic connection they've discovered.

Solution: Bidirectional links between notes. From the note editor, users can link the current note to any other note. Links are visible in both directions — if Note A links to Note B, Note B also shows a link to Note A.

Not included: Automatic link suggestions or graph visualization of linked notes. Links are manually created.

Functional

User flow:

  1. User opens the note editor for a verse
  2. Sees a "Linked notes" section below the text area
  3. Clicks "Link to another note" → picker shows existing notes
  4. Selects a note to link → link is created
  5. Both notes now show the link to each other
  6. User can remove links via a delete button on each linked note

Edge cases:

  • Self-links prevented (can't link a note to itself)
  • Duplicate links prevented
  • Bidirectionality is implemented at query time (single row in DB, OR query)
  • Pro+ tier required

UX & Design

In the note editor:

  • "Linked notes" section below the textarea
  • Each linked note shown as a compact card (reference + preview)
  • "Link to note" button opens a picker modal
  • Picker filters out already-linked notes and self

Technical

DB table: note_links

  • Columns: id (PK), fromNoteId, toNoteId, createdAt
  • Indexes on both fromNoteId and toNoteId
  • Bidirectionality: query with WHERE fromNoteId = X OR toNoteId = X

API:

  • GET /api/notes/[id]/links — get all linked notes (bidirectional)
  • POST /api/notes/[id]/links — create link ({ targetNoteId })
  • DELETE /api/notes/[id]/links — remove link ({ targetNoteId })

Query functions (notes.ts):

  • getNoteLinks(noteId, userId) — fetches linked note IDs via OR condition, then fetches those notes (filtered by userId for security)
  • createNoteLink(fromNoteId, toNoteId) — inserts single directional row
  • deleteNoteLink(fromNoteId, toNoteId) — deletes checking both directions

Tier: Pro+ (noteCrossLinking: true)

Files:

  • apps/web/src/routes/api/notes/[id]/links/+server.ts — GET/POST/DELETE
  • apps/web/src/lib/server/queries/notes.ts — link query functions
  • apps/web/src/lib/components/bible/NoteEditor.svelte — link UI in editor
  • apps/web/src/lib/stores/notes.svelte.tsnoteLinks Map

Status

Current: DONE Milestone: v1 Priority: Medium — Pro differentiator

History:

  • No equivalent in BibleGame — new for web version
  • Bidirectional via OR query rather than two rows for simplicity

Dependencies:

  • Requires: notes system (DONE), tier system (DONE)

Screenshots

Feature screenshot