Add trust features: history, trash, export, and collection sharing
release gate / check (push) Failing after 6m36s
release gate / check (push) Failing after 6m36s
Implement Notion-like upgrade phase 4: append-only page revisions with restore-as-a-new-version; recoverable bookmark/page/collection deletions whose restores never resurrect public flags or shares; owner-scoped JSON export; and explicit, revocable read-only collection sharing with owner-only mutations and no transitive third-party bookmark leaks. Add migration 009, API/docs, integration coverage, and page/collections/trash UI.
This commit is contained in:
@@ -236,6 +236,22 @@ CREATE TABLE "PageLink" (
|
||||
);
|
||||
CREATE INDEX "PageLink_targetPageId_idx" ON "PageLink"("targetPageId");
|
||||
|
||||
-- 2.13c PageRevision: server-side content history. A snapshot is recorded for
|
||||
-- every committed content version (including restore, which is a new version)
|
||||
-- so an old draft can be inspected and restored without ever rewriting the
|
||||
-- past. Revision rows cascade with their page.
|
||||
CREATE TABLE "PageRevision" (
|
||||
id text PRIMARY KEY,
|
||||
"pageId" text NOT NULL REFERENCES "Page"(id) ON DELETE CASCADE,
|
||||
version integer NOT NULL,
|
||||
title text NOT NULL,
|
||||
content text NOT NULL,
|
||||
icon text,
|
||||
"createdAt" timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE ("pageId", version)
|
||||
);
|
||||
CREATE INDEX "PageRevision_pageId_version_idx" ON "PageRevision"("pageId", version DESC);
|
||||
|
||||
-- 2.14 SignalSource
|
||||
CREATE TABLE "SignalSource" (
|
||||
id text PRIMARY KEY,
|
||||
@@ -294,6 +310,22 @@ CREATE TABLE "AppSetting" (
|
||||
"updatedAt" timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- 2.16b Trash: recoverable deletions (trust phase). The row is a private
|
||||
-- per-owner snapshot taken in the same transaction as the hard delete. It
|
||||
-- keeps intrinsic data and owner-scoped relationships, but deliberately not
|
||||
-- access grants (bookmark shares, public flags, collection shares): restoring
|
||||
-- an item never resurrects a grant that was revoked while it sat in the bin.
|
||||
CREATE TABLE "Trash" (
|
||||
id text PRIMARY KEY,
|
||||
"ownerId" text NOT NULL REFERENCES "User"(id) ON DELETE CASCADE,
|
||||
type text NOT NULL CHECK (type IN ('bookmark','page','collection')),
|
||||
"originalId" text NOT NULL,
|
||||
data jsonb NOT NULL,
|
||||
"deletedAt" timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (type, "originalId")
|
||||
);
|
||||
CREATE INDEX "Trash_ownerId_deletedAt_idx" ON "Trash"("ownerId", "deletedAt" DESC);
|
||||
|
||||
-- 2.16 SharedDate
|
||||
CREATE TABLE "SharedDate" (
|
||||
id text PRIMARY KEY,
|
||||
@@ -325,6 +357,19 @@ CREATE TABLE "Collection" (
|
||||
);
|
||||
CREATE INDEX "Collection_ownerId_idx" ON "Collection"("ownerId");
|
||||
|
||||
-- 2.17b CollectionShare: explicit, revocable read access to a collection.
|
||||
-- Recipients get the narrowed bookmark projection for member bookmarks (via
|
||||
-- BookmarkVisible); sharing therefore widens access only by the owner's
|
||||
-- deliberate action, is disclosed in the share UI, and revocation removes
|
||||
-- access immediately. Mutations remain owner-only.
|
||||
CREATE TABLE "CollectionShare" (
|
||||
"collectionId" text NOT NULL REFERENCES "Collection"(id) ON DELETE CASCADE,
|
||||
"userId" text NOT NULL REFERENCES "User"(id) ON DELETE CASCADE,
|
||||
"createdAt" timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY ("collectionId", "userId")
|
||||
);
|
||||
CREATE INDEX "CollectionShare_userId_idx" ON "CollectionShare"("userId");
|
||||
|
||||
CREATE TABLE "CollectionProperty" (
|
||||
id text PRIMARY KEY,
|
||||
"collectionId" text NOT NULL REFERENCES "Collection"(id) ON DELETE CASCADE,
|
||||
|
||||
Reference in New Issue
Block a user