All checks were successful
CD / Build and push images (push) Successful in 1m52s
CI / Lint, typecheck, test (push) Successful in 1m34s
CI / Auth e2e pack (push) Successful in 1m44s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m7s
CD / Promote to Int (push) Successful in 10s
Prisma models `pages`/`page_updates`/`page_content_cache` per data-model.md. Endpoints: POST /ponds/:id/pages (title -> empty Yjs doc state, seeded via y-prosemirror), GET /pages/:id (meta + base64 state), PUT /pages/:id/state (client-encoded Yjs state, rejected above the 5 MiB operations.md limit or if it doesn't decode into a valid document for the schema), PATCH /pages/:id (title/slug — explicit slug changes validate uniqueness per pond, title-only renames keep the slug), DELETE (soft). Access follows InterimAccessService via the page's pond, same 404-not-403 interim rule as ponds. State saves decode the Yjs update with yjs + y-prosemirror and run it through the #24 shared derivation functions (docToPlainText/ docToMarkdown/docToHtml/extractOutline) to refresh page_content_cache. The Yjs XmlFragment name ("default") and the derivation call are factored so the collab server's persistence hooks (#35) can reuse both. Raised the API's JSON body limit to 8 MiB (main.ts and the e2e test app) to fit base64-encoded page state. Closes #23
60 lines
1.9 KiB
SQL
60 lines
1.9 KiB
SQL
-- CreateTable
|
|
CREATE TABLE "pages" (
|
|
"id" TEXT NOT NULL,
|
|
"pond_id" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"slug" TEXT NOT NULL,
|
|
"ydoc_state" BYTEA NOT NULL,
|
|
"sort_key" TEXT NOT NULL,
|
|
"created_by" TEXT NOT NULL,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
"deleted_at" TIMESTAMP(3),
|
|
"deleted_by" TEXT,
|
|
|
|
CONSTRAINT "pages_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "page_updates" (
|
|
"id" TEXT NOT NULL,
|
|
"page_id" TEXT NOT NULL,
|
|
"seq" INTEGER NOT NULL,
|
|
"update" BYTEA NOT NULL,
|
|
|
|
CONSTRAINT "page_updates_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "page_content_cache" (
|
|
"page_id" TEXT NOT NULL,
|
|
"plain_text" TEXT NOT NULL,
|
|
"markdown" TEXT NOT NULL,
|
|
"html" TEXT NOT NULL,
|
|
"outline" JSONB NOT NULL,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "page_content_cache_pkey" PRIMARY KEY ("page_id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "pages_pond_id_idx" ON "pages"("pond_id");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "pages_pond_id_slug_key" ON "pages"("pond_id", "slug");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "page_updates_page_id_seq_key" ON "page_updates"("page_id", "seq");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "pages" ADD CONSTRAINT "pages_pond_id_fkey" FOREIGN KEY ("pond_id") REFERENCES "ponds"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "pages" ADD CONSTRAINT "pages_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "page_updates" ADD CONSTRAINT "page_updates_page_id_fkey" FOREIGN KEY ("page_id") REFERENCES "pages"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "page_content_cache" ADD CONSTRAINT "page_content_cache_page_id_fkey" FOREIGN KEY ("page_id") REFERENCES "pages"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|