-- ---------------------------------------------------------------------------
-- O irmao no PostgreSQL de `scripts/migracao-assistentes-anthropic.sql` (08/11/2026, a
-- fatia 133, ASSISTENTES-PORTA-DO-CLAUDE; o desenho
-- `docs/f3-telas-restantes/assistentes-anthropic.md`, 2.3), para a COPIA LOCAL de pe -- as
-- colunas e as tabelas como o `scripts/gerar-ddl-postgres.php` as emite, tiradas linha a
-- linha do `postgres/schema.sql`: o inquilino na frente da chave primaria que nao e o id e
-- de todo indice, as chaves estrangeiras, o RLS ligado e forcado e a politica. Os bancos da
-- suite, o do contrato e a producao nascem do `postgres/schema.sql`; a producao recebe as
-- linhas do MySQL pela carga (`scripts/migrar-dados.sh`), depois do passo 0 de la.
--
--   docker exec -i franquiabv-postgres-1 sh -c 'psql -U "$POSTGRES_USER" -d franquiabv_dev -v ON_ERROR_STOP=1' \
--     < postgres/migracao-assistentes-anthropic.sql
--
-- IDEMPOTENTE, numa transacao so, com a conferencia de ausencia dentro dela: as colunas
-- so entram se `assistentes.instrucoes` nao existe, e cada tabela so se ainda nao existe
-- ("ja existe: nada feito"). Os privilegios do `bvip_app` vem do `ALTER DEFAULT
-- PRIVILEGES` do esquema, e sao dados de novo aqui, para a copia montada por outro papel.
-- NENHUM DELETE. PARA DESFAZER: `DROP TABLE` das quatro (mensagens antes de conversas) e
-- `ALTER TABLE assistentes DROP COLUMN` das cinco.
-- ---------------------------------------------------------------------------

SET client_encoding = 'UTF8';

BEGIN;

DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM information_schema.columns
                WHERE table_schema = current_schema() AND table_name = 'assistentes' AND column_name = 'instrucoes') THEN
        RAISE NOTICE 'assistentes: colunas ja existem, nada feito';
    ELSE
        ALTER TABLE assistentes
            ADD COLUMN instrucoes       text,
            ADD COLUMN modelo           varchar(40) NOT NULL DEFAULT 'claude-haiku-5-5',
            ADD COLUMN esforco          varchar(10) NOT NULL DEFAULT 'low',
            ADD COLUMN limite_de_tokens integer NOT NULL DEFAULT '4096',
            ADD COLUMN pagina_publica   varchar(30) DEFAULT NULL;

        CREATE UNIQUE INDEX assistentes_UNQ_ASSISTENTES_pagina_publica ON assistentes (inquilino_id, pagina_publica);
    END IF;

    IF to_regclass('assistentes_conversas') IS NOT NULL THEN
        RAISE NOTICE 'assistentes_conversas ja existe: nada feito';
    ELSE
        CREATE TABLE assistentes_conversas (
            inquilino_id                     integer NOT NULL DEFAULT current_setting('app.inquilino_id')::integer,
            id                               integer GENERATED BY DEFAULT AS IDENTITY,
            assistente                       integer NOT NULL,
            usuario                          integer NOT NULL,
            unidade                          integer NOT NULL,
            pagina                           varchar(30) DEFAULT NULL,
            sistema                          text NOT NULL,
            modelo                           varchar(40) NOT NULL,
            descartar_blocos                 boolean NOT NULL DEFAULT false,
            data_criacao                     timestamptz NOT NULL,
            data_ultima                      timestamptz NOT NULL,
            PRIMARY KEY (id)
        );

        CREATE INDEX assistentes_conversas_IDX_ASSISTENTES_CONVERSAS_usuario_data ON assistentes_conversas (inquilino_id, usuario, data_ultima);
        CREATE INDEX assistentes_conversas_FK_ASSISTENTES_CONVERSAS_assistente ON assistentes_conversas (inquilino_id, assistente);
        CREATE INDEX assistentes_conversas_FK_ASSISTENTES_CONVERSAS_unidade ON assistentes_conversas (inquilino_id, unidade);

        ALTER TABLE assistentes_conversas ADD CONSTRAINT FK_ASSISTENTES_CONVERSAS_assistente FOREIGN KEY (assistente) REFERENCES assistentes (id);
        ALTER TABLE assistentes_conversas ADD CONSTRAINT FK_ASSISTENTES_CONVERSAS_unidade FOREIGN KEY (unidade) REFERENCES unidades (id);
        ALTER TABLE assistentes_conversas ADD CONSTRAINT FK_ASSISTENTES_CONVERSAS_usuario FOREIGN KEY (usuario) REFERENCES usuarios (id);

        ALTER TABLE assistentes_conversas ADD CONSTRAINT assistentes_conversas_inquilino_fk
            FOREIGN KEY (inquilino_id) REFERENCES inquilinos (id);
        ALTER TABLE assistentes_conversas ENABLE ROW LEVEL SECURITY;
        ALTER TABLE assistentes_conversas FORCE  ROW LEVEL SECURITY;
        CREATE POLICY inquilino_isolado ON assistentes_conversas
            USING      (inquilino_id = current_setting('app.inquilino_id')::integer)
            WITH CHECK (inquilino_id = current_setting('app.inquilino_id')::integer);
    END IF;

    IF to_regclass('assistentes_cota') IS NOT NULL THEN
        RAISE NOTICE 'assistentes_cota ja existe: nada feito';
    ELSE
        CREATE TABLE assistentes_cota (
            inquilino_id                     integer NOT NULL DEFAULT current_setting('app.inquilino_id')::integer,
            dia                              date NOT NULL,
            chave                            varchar(80) NOT NULL,
            usados                           integer NOT NULL DEFAULT '0',
            PRIMARY KEY (inquilino_id, dia, chave)
        );

        ALTER TABLE assistentes_cota ADD CONSTRAINT assistentes_cota_inquilino_fk
            FOREIGN KEY (inquilino_id) REFERENCES inquilinos (id);
        ALTER TABLE assistentes_cota ENABLE ROW LEVEL SECURITY;
        ALTER TABLE assistentes_cota FORCE  ROW LEVEL SECURITY;
        CREATE POLICY inquilino_isolado ON assistentes_cota
            USING      (inquilino_id = current_setting('app.inquilino_id')::integer)
            WITH CHECK (inquilino_id = current_setting('app.inquilino_id')::integer);
    END IF;

    IF to_regclass('assistentes_mensagens') IS NOT NULL THEN
        RAISE NOTICE 'assistentes_mensagens ja existe: nada feito';
    ELSE
        CREATE TABLE assistentes_mensagens (
            inquilino_id                     integer NOT NULL DEFAULT current_setting('app.inquilino_id')::integer,
            id                               integer GENERATED BY DEFAULT AS IDENTITY,
            conversa                         integer NOT NULL,
            papel                            varchar(10) NOT NULL,
            conteudo                         text NOT NULL,
            motivo_de_parada                 varchar(30) DEFAULT NULL,
            modelo_que_respondeu             varchar(40) DEFAULT NULL,
            fora_do_historico                boolean NOT NULL DEFAULT false,
            data_criacao                     timestamptz NOT NULL,
            PRIMARY KEY (id)
        );

        CREATE INDEX assistentes_mensagens_FK_ASSISTENTES_MENSAGENS_conversa ON assistentes_mensagens (inquilino_id, conversa);

        ALTER TABLE assistentes_mensagens ADD CONSTRAINT FK_ASSISTENTES_MENSAGENS_conversa FOREIGN KEY (conversa) REFERENCES assistentes_conversas (id) ON DELETE CASCADE;

        ALTER TABLE assistentes_mensagens ADD CONSTRAINT assistentes_mensagens_inquilino_fk
            FOREIGN KEY (inquilino_id) REFERENCES inquilinos (id);
        ALTER TABLE assistentes_mensagens ENABLE ROW LEVEL SECURITY;
        ALTER TABLE assistentes_mensagens FORCE  ROW LEVEL SECURITY;
        CREATE POLICY inquilino_isolado ON assistentes_mensagens
            USING      (inquilino_id = current_setting('app.inquilino_id')::integer)
            WITH CHECK (inquilino_id = current_setting('app.inquilino_id')::integer);
    END IF;

    IF to_regclass('assistentes_uso') IS NOT NULL THEN
        RAISE NOTICE 'assistentes_uso ja existe: nada feito';
    ELSE
        CREATE TABLE assistentes_uso (
            inquilino_id                     integer NOT NULL DEFAULT current_setting('app.inquilino_id')::integer,
            id                               integer GENERATED BY DEFAULT AS IDENTITY,
            dia                              date NOT NULL,
            assistente                       integer NOT NULL,
            usuario                          integer DEFAULT NULL,
            unidade                          integer DEFAULT NULL,
            pagina                           varchar(30) DEFAULT NULL,
            pedidos                          integer NOT NULL DEFAULT '0',
            tokens_entrada                   integer NOT NULL DEFAULT '0',
            tokens_saida                     integer NOT NULL DEFAULT '0',
            tokens_cache_lidos               integer NOT NULL DEFAULT '0',
            tokens_cache_gravados            integer NOT NULL DEFAULT '0',
            custo_estimado_usd               numeric(12,6) NOT NULL DEFAULT '0.000000',
            recusas                          integer NOT NULL DEFAULT '0',
            erros                            integer NOT NULL DEFAULT '0',
            PRIMARY KEY (id)
        );

        CREATE INDEX assistentes_uso_IDX_ASSISTENTES_USO_dia ON assistentes_uso (inquilino_id, dia);
        CREATE INDEX assistentes_uso_FK_ASSISTENTES_USO_assistente ON assistentes_uso (inquilino_id, assistente);

        ALTER TABLE assistentes_uso ADD CONSTRAINT FK_ASSISTENTES_USO_assistente FOREIGN KEY (assistente) REFERENCES assistentes (id);

        ALTER TABLE assistentes_uso ADD CONSTRAINT assistentes_uso_inquilino_fk
            FOREIGN KEY (inquilino_id) REFERENCES inquilinos (id);
        ALTER TABLE assistentes_uso ENABLE ROW LEVEL SECURITY;
        ALTER TABLE assistentes_uso FORCE  ROW LEVEL SECURITY;
        CREATE POLICY inquilino_isolado ON assistentes_uso
            USING      (inquilino_id = current_setting('app.inquilino_id')::integer)
            WITH CHECK (inquilino_id = current_setting('app.inquilino_id')::integer);
    END IF;

    IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'bvip_app') THEN
        GRANT SELECT, INSERT, UPDATE, DELETE ON assistentes_conversas, assistentes_cota, assistentes_mensagens, assistentes_uso TO bvip_app;
        GRANT USAGE, SELECT ON SEQUENCE assistentes_conversas_id_seq, assistentes_mensagens_id_seq, assistentes_uso_id_seq TO bvip_app;
    END IF;
END
$$;

COMMIT;

-- Conferencia: as cinco colunas, o RLS ligado e forcado das quatro, os privilegios do
-- `bvip_app` e as linhas (0).
SELECT column_name AS coluna, data_type AS tipo, column_default AS padrao
  FROM information_schema.columns
 WHERE table_schema = current_schema() AND table_name = 'assistentes'
   AND column_name IN ('instrucoes', 'modelo', 'esforco', 'limite_de_tokens', 'pagina_publica')
 ORDER BY ordinal_position;

SELECT relname AS tabela, relrowsecurity AS rls, relforcerowsecurity AS forcado
  FROM pg_class
 WHERE relname IN ('assistentes_conversas', 'assistentes_cota', 'assistentes_mensagens', 'assistentes_uso')
   AND relkind = 'r'
 ORDER BY relname;

SELECT table_name AS tabela, string_agg(privilege_type, ',' ORDER BY privilege_type) AS privilegios_do_bvip_app
  FROM information_schema.role_table_grants
 WHERE table_name IN ('assistentes_conversas', 'assistentes_cota', 'assistentes_mensagens', 'assistentes_uso')
   AND grantee = 'bvip_app'
 GROUP BY table_name
 ORDER BY table_name;

SET app.inquilino_id = '1';

SELECT (SELECT COUNT(*) FROM assistentes_conversas) AS conversas,
       (SELECT COUNT(*) FROM assistentes_mensagens) AS mensagens,
       (SELECT COUNT(*) FROM assistentes_cota)      AS cota,
       (SELECT COUNT(*) FROM assistentes_uso)       AS uso;
