-- Kern-Entitaeten des DMS (FDN-02): Dokument, Datei-Revision, Ordner, Tag,
-- Metadatenfeld. Laeuft in der DB EINES Mandanten (Modell C, siehe Core
-- TEN-01) — keine tenant_id-Spalte, die Tenant-Zugehoerigkeit ist implizit
-- durch die Datenbankverbindung gegeben. FK auf users(id) spiegelt das
-- Benutzer-Datenmodell aus Core IAM-01 (migrations/tenant/0001_users.up.sql
-- im NEXARCH-Core-Modul) — Auth/Benutzerverwaltung liegt vollstaendig in
-- Core (siehe "Nicht Bestandteil" in FDN-02), diese Migration dupliziert sie
-- NICHT, sondern setzt sie als bereits vorhanden voraus (users-Tabelle wird
-- durch Cores eigene Migration in derselben physischen Tenant-Datenbank
-- angelegt, bevor DMS-Migrationen laufen).
CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE TABLE folders (
    id               UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    parent_folder_id UUID REFERENCES folders(id) ON DELETE CASCADE,
    name             TEXT NOT NULL,
    created_by       UUID NOT NULL REFERENCES users(id),
    created_at       TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at       TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_folders_parent_folder_id ON folders(parent_folder_id);

CREATE TABLE documents (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    folder_id           UUID REFERENCES folders(id) ON DELETE SET NULL,
    title               TEXT NOT NULL,
    -- current_revision_id verweist erst NACH der Anlage von file_revisions
    -- auf eine Zeile (siehe ALTER TABLE unten) — beim INSERT eines Dokuments
    -- existiert noch keine Revision, daher NULLable und zirkulaer per
    -- nachtraeglichem FOREIGN KEY statt Inline-Referenz geloest.
    current_revision_id UUID,
    created_by          UUID NOT NULL REFERENCES users(id),
    created_at          TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at          TIMESTAMPTZ NOT NULL DEFAULT now(),
    deleted_at          TIMESTAMPTZ
);
CREATE INDEX idx_documents_folder_id ON documents(folder_id);
CREATE INDEX idx_documents_created_by ON documents(created_by);

CREATE TABLE file_revisions (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    document_id     UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE,
    revision_number INT NOT NULL,
    -- storage_key ist ein Platzhalter fuer die Objekt-Storage-Abstraktion
    -- (FDN-03, "Nicht Bestandteil" dieser Kachel) — hier nur die Spalte, die
    -- spaetere Kachel legt fest, was tatsaechlich dahinter liegt.
    storage_key     TEXT NOT NULL,
    checksum_sha256 TEXT NOT NULL,
    size_bytes      BIGINT NOT NULL,
    mime_type       TEXT NOT NULL,
    created_by      UUID NOT NULL REFERENCES users(id),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (document_id, revision_number)
);
CREATE INDEX idx_file_revisions_document_id ON file_revisions(document_id);

ALTER TABLE documents
    ADD CONSTRAINT fk_documents_current_revision
    FOREIGN KEY (current_revision_id) REFERENCES file_revisions(id) ON DELETE SET NULL;

CREATE TABLE tags (
    id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name       TEXT NOT NULL UNIQUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE document_tags (
    document_id UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE,
    tag_id      UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
    PRIMARY KEY (document_id, tag_id)
);
CREATE INDEX idx_document_tags_tag_id ON document_tags(tag_id);

CREATE TABLE metadata_fields (
    id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    field_key  TEXT NOT NULL UNIQUE,
    label      TEXT NOT NULL,
    field_type TEXT NOT NULL CHECK (field_type IN ('text', 'number', 'date', 'bool', 'select')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE document_metadata_values (
    document_id UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE,
    field_id    UUID NOT NULL REFERENCES metadata_fields(id) ON DELETE CASCADE,
    value       TEXT NOT NULL,
    PRIMARY KEY (document_id, field_id)
);
CREATE INDEX idx_document_metadata_values_field_id ON document_metadata_values(field_id);
