feat(acadenice): add bidirectional backlinks + wikilinks for R3.2
- Migration: acadenice_backlink table (source/target/link_type/excerpt/workspace)
with 3 indexes and UNIQUE(source,target,type) constraint. Up+down.
- Backend module AcadeniceBacklinksModule:
BacklinkParserService: walks Tiptap JSON, extracts wikilinks/mentions/databaseView.
BacklinkIndexerService: idempotent delete-then-insert per page save.
BacklinkService: permission-aware query (space_members / public visibility).
BacklinksController: GET /api/acadenice/pages/:pageId/backlinks (JWT auth).
PageContentUpdatedListener: OnEvent handler for collab saves -> async reindex.
Tests: 16 Vitest specs (parser/indexer/service/controller).
- PersistenceExtension patch: emits ACADENICE_PAGE_CONTENT_UPDATED_EVENT after
each collab onStoreDocument (fire-and-forget, no impact on save path).
- CoreModule patch: imports AcadeniceBacklinksModule.
- Frontend WikilinkExtension: Tiptap inline atom node, [[Title]] / [[Title|alias]],
Suggestion popup (reuses mention pattern + floating-ui), ReactNodeView with
broken-link state, insertWikilink command.
Tests: 9 Vitest specs (schema/attrs/commands/HTML parse+render).
- LinkedReferencesPanel: React Query useBacklinks(pageId, staleTime=30s),
accordion grouped by link_type, excerpt preview, navigate to source page.
Tests: 7 Vitest specs (loading/error/empty/render/navigate/groups).
- extensions.ts patch: + WikilinkExtension in mainExtensions[].
- full-editor.tsx patch: + LinkedReferencesPanel below editor (Divider + panel).
- i18n: 11 keys added in en-US and fr-FR (backlinks.* + wikilink.*).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>