All checks were successful
CD / Build and push images (push) Successful in 3m2s
CI / Lint, typecheck, test (push) Successful in 2m16s
CI / Auth e2e pack (push) Successful in 2m44s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m16s
CD / Promote to Int (push) Successful in 11s
Maintain a server-side `page_links` index on every content change so
backlinks and missing-target ("phantom") links can be queried.
- prisma: `PageLink` (from_page_id, nullable to_page_id, target_slug;
unique per (from, slug); cascade on source purge, set-null on target
purge); migration.
- shared: `extractWikilinkSlugs(doc)` (distinct target slugs) and the
`BacklinkView` / `PhantomLinkView` read shapes.
- collab: the persistence hook (#35) now rewrites the source page's outgoing
links in the same transaction as the content cache — one row per distinct
wikilink slug, resolved to a page in the same pond (null = phantom).
- api: `GET /pages/:id/backlinks` (permission-filtered — wikilinks resolve
within a pond, so seeing the pond is the read right) and
`GET /ponds/:id/phantom-links` (missing targets grouped with their
referrers). Creating or renaming a page to a slug that pages already link
to resolves those phantom rows; because links store the target's id,
backlinks survive a later rename of the target's slug.
- tests: shared extraction unit test; collab persistence db test (store
writes resolved + phantom rows and rewrites the index); api LinksService
db test (backlinks, permission filter, phantom aggregation, create/rename
resolution, id-based backlinks survive target rename).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PGdhRiwU1WRL4XxJfZYipY
25 lines
874 B
SQL
25 lines
874 B
SQL
-- CreateTable
|
|
CREATE TABLE "page_links" (
|
|
"id" TEXT NOT NULL,
|
|
"from_page_id" TEXT NOT NULL,
|
|
"to_page_id" TEXT,
|
|
"target_slug" TEXT NOT NULL,
|
|
|
|
CONSTRAINT "page_links_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "page_links_to_page_id_idx" ON "page_links"("to_page_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "page_links_target_slug_idx" ON "page_links"("target_slug");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "page_links_from_page_id_target_slug_key" ON "page_links"("from_page_id", "target_slug");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "page_links" ADD CONSTRAINT "page_links_from_page_id_fkey" FOREIGN KEY ("from_page_id") REFERENCES "pages"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "page_links" ADD CONSTRAINT "page_links_to_page_id_fkey" FOREIGN KEY ("to_page_id") REFERENCES "pages"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|