-- 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");
