CREATE TABLE knowledge_groups (
    id          BIGSERIAL PRIMARY KEY,
    tenant_id   BIGINT NOT NULL REFERENCES tenants(id),
    name        VARCHAR(100) NOT NULL,
    parent_id   BIGINT REFERENCES knowledge_groups(id) ON DELETE SET NULL,
    sort_order  INT NOT NULL DEFAULT 0,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at  TIMESTAMPTZ
);
CREATE UNIQUE INDEX uk_knowledge_group_name
    ON knowledge_groups(tenant_id, COALESCE(parent_id, 0), name)
    WHERE deleted_at IS NULL;
CREATE INDEX idx_knowledge_group_tenant_parent
    ON knowledge_groups(tenant_id, parent_id, sort_order)
    WHERE deleted_at IS NULL;

CREATE TABLE knowledge_items (
    id           BIGSERIAL PRIMARY KEY,
    tenant_id    BIGINT NOT NULL REFERENCES tenants(id),
    group_id     BIGINT NOT NULL REFERENCES knowledge_groups(id),
    source_type  VARCHAR(20) NOT NULL,
    name         VARCHAR(255) NOT NULL,
    source_uri   TEXT,
    storage_key  TEXT NOT NULL DEFAULT '',
    content_text TEXT,
    status       VARCHAR(20) NOT NULL DEFAULT 'pending',
    size_bytes   BIGINT NOT NULL DEFAULT 0,
    item_version INT NOT NULL DEFAULT 1,
    error_message TEXT,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at   TIMESTAMPTZ
);
CREATE INDEX idx_knowledge_item_group_status
    ON knowledge_items(tenant_id, group_id, status)
    WHERE deleted_at IS NULL;

CREATE TABLE knowledge_parse_tasks (
    id                BIGSERIAL PRIMARY KEY,
    tenant_id         BIGINT NOT NULL REFERENCES tenants(id),
    knowledge_item_id BIGINT NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
    source_type       VARCHAR(20) NOT NULL,
    status            VARCHAR(20) NOT NULL DEFAULT 'pending',
    error_message     TEXT,
    started_at        TIMESTAMPTZ,
    completed_at      TIMESTAMPTZ,
    created_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at        TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_parse_task_status
    ON knowledge_parse_tasks(tenant_id, status, created_at DESC);

CREATE TABLE knowledge_chunks_meta (
    id                BIGSERIAL PRIMARY KEY,
    tenant_id         BIGINT NOT NULL REFERENCES tenants(id),
    knowledge_item_id BIGINT NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
    chunk_index       INT NOT NULL,
    token_count       INT NOT NULL DEFAULT 0,
    qdrant_point_id   VARCHAR(64) NOT NULL,
    item_version      INT NOT NULL DEFAULT 1,
    status            VARCHAR(20) NOT NULL DEFAULT 'active',
    created_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (knowledge_item_id, chunk_index, item_version)
);
CREATE INDEX idx_chunk_item_version
    ON knowledge_chunks_meta(tenant_id, knowledge_item_id, item_version, status);

CREATE TABLE prompt_rule_knowledge_groups (
    prompt_rule_id      BIGINT NOT NULL REFERENCES prompt_rules(id) ON DELETE CASCADE,
    knowledge_group_id  BIGINT NOT NULL REFERENCES knowledge_groups(id) ON DELETE CASCADE,
    created_at          TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (prompt_rule_id, knowledge_group_id)
);
CREATE INDEX idx_prompt_rule_knowledge_group
    ON prompt_rule_knowledge_groups(knowledge_group_id, prompt_rule_id);
