feat(documents): document_folders schema + folder_id on documents
Adds a per-port folder tree (self-FK on parent_id, unlimited depth) plus a nullable folder_id on documents (null = root). Sibling-name uniqueness enforced via a unique index on (port_id, COALESCE(parent_id, '__root__'), LOWER(name)) so two folders can't share a name inside the same parent. ON DELETE SET NULL on documents.folder_id and ON DELETE NO ACTION on the parent self-FK so a botched delete never silently destroys data — the service layer implements soft-rescue (bubble children up to parent) instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
33
src/lib/db/migrations/0050_document_folders.sql
Normal file
33
src/lib/db/migrations/0050_document_folders.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
-- Document folders: per-port, unlimited-depth tree. parent_id references
|
||||
-- another document_folders row; null = root. Sibling-name uniqueness is
|
||||
-- enforced via a partial-uniqueness on (port_id, COALESCE(parent_id,
|
||||
-- '__root__'), LOWER(name)) so two folders can't share a name inside
|
||||
-- the same parent. The CRM checks parent_id chain for cycles in the
|
||||
-- service layer; no DB-side cycle guard.
|
||||
CREATE TABLE IF NOT EXISTS "document_folders" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"port_id" text NOT NULL REFERENCES "ports" ("id"),
|
||||
"parent_id" text,
|
||||
"name" text NOT NULL,
|
||||
"created_by" text NOT NULL,
|
||||
"created_at" timestamp with time zone NOT NULL DEFAULT now(),
|
||||
"updated_at" timestamp with time zone NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
ALTER TABLE "document_folders"
|
||||
ADD CONSTRAINT "document_folders_parent_fk"
|
||||
FOREIGN KEY ("parent_id") REFERENCES "document_folders" ("id")
|
||||
ON DELETE NO ACTION;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "idx_document_folders_port"
|
||||
ON "document_folders" ("port_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_document_folders_parent"
|
||||
ON "document_folders" ("parent_id");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "uniq_document_folders_sibling_name"
|
||||
ON "document_folders" ("port_id", COALESCE("parent_id", '__root__'), LOWER("name"));
|
||||
|
||||
ALTER TABLE "documents"
|
||||
ADD COLUMN IF NOT EXISTS "folder_id" text REFERENCES "document_folders" ("id") ON DELETE SET NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "idx_docs_folder"
|
||||
ON "documents" ("folder_id");
|
||||
Reference in New Issue
Block a user