Refatoracao geral: limpeza de logs, correcoes de fim de linha, animacoes framer-motion e automacao de deploy no package.json

This commit is contained in:
2026-03-23 11:36:35 +00:00
parent a4450ad7e5
commit 75c75f6547
52 changed files with 9525 additions and 9544 deletions

View File

@@ -1,340 +1,340 @@
-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================
-- TABELA: USUARIOS
-- ============================================
CREATE TABLE usuarios (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) NOT NULL UNIQUE,
nome_completo VARCHAR(255) NOT NULL,
perfil VARCHAR(50) CHECK (perfil IN ('admin', 'gerente_qualidade', 'engenheiro', 'cliente')) DEFAULT 'engenheiro',
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_usuarios_email ON usuarios(email);
CREATE INDEX idx_usuarios_perfil ON usuarios(perfil);
-- ============================================
-- TABELA: CLIENTES
-- ============================================
CREATE TABLE clientes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(255) NOT NULL,
contato VARCHAR(255),
email VARCHAR(255),
telefone VARCHAR(20),
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_clientes_nome ON clientes(nome);
-- ============================================
-- TABELA: TEMPLATES_TOPICOS
-- ============================================
CREATE TABLE templates_topicos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
numero_topico VARCHAR(20) NOT NULL,
titulo VARCHAR(255) NOT NULL,
descricao TEXT,
obrigatorio BOOLEAN DEFAULT FALSE,
ordem INTEGER,
tipo_documentos TEXT[],
tags_padrao TEXT[],
categoria VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_topicos_numero ON templates_topicos(numero_topico);
CREATE INDEX idx_topicos_categoria ON templates_topicos(categoria);
-- ============================================
-- TABELA: TEMPLATES_CUSTOMIZADOS
-- ============================================
CREATE TABLE templates_customizados (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(255) NOT NULL UNIQUE,
tipo VARCHAR(50) CHECK (tipo IN ('novo', 'derivado')) DEFAULT 'novo',
template_pai_id UUID REFERENCES templates_customizados(id) ON DELETE SET NULL,
topicos_selecionados TEXT[],
total_topicos INTEGER,
total_obrigatorios INTEGER,
descricao TEXT,
ativo BOOLEAN DEFAULT TRUE,
criado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_templates_nome ON templates_customizados(nome);
CREATE INDEX idx_templates_tipo ON templates_customizados(tipo);
-- ============================================
-- TABELA: PROJETOS
-- ============================================
CREATE TABLE projetos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
numero_projeto VARCHAR(100) NOT NULL UNIQUE,
nome_projeto VARCHAR(255) NOT NULL,
cliente_id UUID REFERENCES clientes(id) ON DELETE CASCADE,
template_id UUID REFERENCES templates_customizados(id) ON DELETE SET NULL,
status VARCHAR(50) CHECK (status IN ('rascunho', 'em_andamento', 'revisao', 'finalizado', 'cancelado')) DEFAULT 'rascunho',
progresso_percentual INTEGER DEFAULT 0,
data_inicio DATE,
data_entrega_prevista DATE,
responsavel_id UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_projetos_numero ON projetos(numero_projeto);
CREATE INDEX idx_projetos_status ON projetos(status);
CREATE INDEX idx_projetos_cliente ON projetos(cliente_id);
-- ============================================
-- TABELA: DATABOOKS_MESTRES
-- ============================================
CREATE TABLE databooks_mestres (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
projeto_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
cliente_nome VARCHAR(255),
cliente_contato VARCHAR(255),
cliente_email VARCHAR(255),
cliente_telefone VARCHAR(20),
produto_nome VARCHAR(255) NOT NULL,
produto_tipo VARCHAR(100),
produto_descricao TEXT,
produto_normas TEXT[],
numero_projeto VARCHAR(100),
ordem_compra VARCHAR(100),
data_inicio DATE,
data_entrega_prevista DATE,
responsavel_id UUID,
revisao_numero VARCHAR(20) DEFAULT 'Rev. 0',
revisao_data TIMESTAMP DEFAULT NOW(),
revisao_autor_id UUID,
revisao_motivo TEXT,
logo_empresa_url TEXT,
logo_cliente_url TEXT,
marca_agua_url TEXT,
cor_primaria VARCHAR(7),
cor_secundaria VARCHAR(7),
titulo_principal VARCHAR(255),
subtitulo VARCHAR(255),
texto_rodape_capa TEXT,
tamanho_pagina VARCHAR(20) CHECK (tamanho_pagina IN ('A4', 'Letter')) DEFAULT 'A4',
orientacao VARCHAR(20) CHECK (orientacao IN ('retrato', 'paisagem')) DEFAULT 'retrato',
margem_superior_mm NUMERIC(5,2) DEFAULT 20,
margem_lateral_mm NUMERIC(5,2) DEFAULT 20,
incluir_marca_agua BOOLEAN DEFAULT TRUE,
incluir_numero_pagina BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_mestres_projeto ON databooks_mestres(projeto_id);
-- ============================================
-- TABELA: SECOES_DATABOOK
-- ============================================
CREATE TABLE secoes_databook (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
projeto_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
topico_id UUID REFERENCES templates_topicos(id),
numero_secao VARCHAR(20) NOT NULL,
titulo VARCHAR(255) NOT NULL,
ordem INTEGER,
status VARCHAR(50) CHECK (status IN ('completo', 'incompleto', 'nao_aplicavel')) DEFAULT 'incompleto',
total_documentos INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_secoes_projeto ON secoes_databook(projeto_id);
CREATE INDEX idx_secoes_numero ON secoes_databook(numero_secao);
-- ============================================
-- TABELA: CONFIGURACOES_PASTAS
-- ============================================
CREATE TABLE configuracoes_pastas (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tipo_documento VARCHAR(100) NOT NULL,
caminho_local TEXT NOT NULL,
caminho_subtipo VARCHAR(100),
caminho_completo TEXT,
habilitado BOOLEAN DEFAULT TRUE,
frequencia_atualizacao VARCHAR(50) CHECK (frequencia_atualizacao IN ('manual', 'ao_criar', 'diario', 'semanal')) DEFAULT 'ao_criar',
ultima_atualizacao TIMESTAMP,
incluir_subpastas BOOLEAN DEFAULT TRUE,
formatos_aceitos TEXT[],
tamanho_maximo_mb INTEGER DEFAULT 50,
tags_obrigatorias TEXT[],
palavras_chave_filtro TEXT[],
palavras_chave_excluir TEXT[],
ordem_docs VARCHAR(50) CHECK (ordem_docs IN ('data', 'nome', 'relevancia')) DEFAULT 'data',
criado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_pastas_tipo ON configuracoes_pastas(tipo_documento);
-- ============================================
-- TABELA: INTEGRACAO_IA
-- ============================================
CREATE TABLE integracao_ia (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
provider VARCHAR(50) CHECK (provider IN ('openai', 'claude', 'gemini')) NOT NULL,
api_key_encriptada TEXT NOT NULL,
modelo_padrao VARCHAR(100),
maximo_tokens INTEGER DEFAULT 2000,
ativo BOOLEAN DEFAULT FALSE,
testado_em TIMESTAMP,
teste_status VARCHAR(50),
teste_mensagem TEXT,
criado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- ============================================
-- TABELA: DOCUMENTOS_AUTO_INDEXADOS
-- ============================================
CREATE TABLE documentos_auto_indexados (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
databook_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
secao_id UUID REFERENCES secoes_databook(id) ON DELETE SET NULL,
secao_numero VARCHAR(20),
titulo VARCHAR(255) NOT NULL,
numero_documento VARCHAR(100),
revisao VARCHAR(20),
arquivo_url TEXT NOT NULL,
arquivo_tipo VARCHAR(50),
conteudo_texto TEXT,
tags_automaticas TEXT[],
tags_usuario TEXT[],
relevancia_score NUMERIC(3,2),
confianca_classificacao NUMERIC(3,2),
ordem_na_secao INTEGER,
data_documento DATE,
aprovado BOOLEAN DEFAULT FALSE,
processado_por_ia VARCHAR(50),
processado_em TIMESTAMP,
criado_em TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_auto_databook ON documentos_auto_indexados(databook_id);
CREATE INDEX idx_auto_secao ON documentos_auto_indexados(secao_numero);
-- ============================================
-- TABELA: LOG_PROCESSAMENTO_IA
-- ============================================
CREATE TABLE log_processamento_ia (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
databook_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
inicio_processamento TIMESTAMP,
fim_processamento TIMESTAMP,
duracao_segundos INTEGER,
total_documentos_encontrados INTEGER,
total_documentos_indexados INTEGER,
total_erros INTEGER,
pastas_varridas TEXT[],
provider_ia VARCHAR(50),
modelo_usado VARCHAR(100),
tokens_utilizados INTEGER,
status VARCHAR(50) CHECK (status IN ('sucesso', 'parcial', 'erro')) DEFAULT 'sucesso',
mensagem_erro TEXT,
iniciado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_log_ia_databook ON log_processamento_ia(databook_id);
-- ============================================
-- TABELA: PERMISSOES_USUARIO_DETALHADAS
-- ============================================
CREATE TABLE permissoes_usuario_detalhadas (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
usuario_id UUID NOT NULL REFERENCES usuarios(id) ON DELETE CASCADE,
pode_criar_template BOOLEAN DEFAULT FALSE,
pode_editar_template BOOLEAN DEFAULT FALSE,
pode_deletar_template BOOLEAN DEFAULT FALSE,
pode_criar_databook BOOLEAN DEFAULT FALSE,
pode_editar_databook BOOLEAN DEFAULT FALSE,
pode_deletar_databook BOOLEAN DEFAULT FALSE,
pode_upload_documentos BOOLEAN DEFAULT FALSE,
pode_aprovar_documentos BOOLEAN DEFAULT FALSE,
pode_gerar_pdf BOOLEAN DEFAULT FALSE,
pode_visualizar_preview BOOLEAN DEFAULT FALSE,
pode_acessar_logs BOOLEAN DEFAULT FALSE,
pode_configurar_ia BOOLEAN DEFAULT FALSE,
pode_configurar_pastas BOOLEAN DEFAULT FALSE,
pode_gerenciar_usuarios BOOLEAN DEFAULT FALSE,
acesso_apenas_seus_projetos BOOLEAN DEFAULT TRUE,
pode_visualizar_precos BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(usuario_id)
);
-- ============================================
-- VIEWS
-- ============================================
CREATE OR REPLACE VIEW view_projetos_resumo AS
SELECT
p.id,
p.numero_projeto,
p.nome_projeto,
p.status,
p.progresso_percentual,
c.nome as cliente_nome,
tc.nome as template_nome,
COUNT(DISTINCT sd.id) as total_secoes,
COUNT(DISTINCT dai.id) as total_documentos,
p.created_at
FROM projetos p
LEFT JOIN clientes c ON p.cliente_id = c.id
LEFT JOIN templates_customizados tc ON p.template_id = tc.id
LEFT JOIN secoes_databook sd ON p.id = sd.projeto_id
LEFT JOIN documentos_auto_indexados dai ON p.id = dai.databook_id
GROUP BY p.id, c.nome, tc.nome
ORDER BY p.created_at DESC;
-- ============================================
-- TRIGGERS
-- ============================================
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_templates_updated_at BEFORE UPDATE ON templates_customizados
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_projetos_updated_at BEFORE UPDATE ON projetos
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_databooks_mestres_updated_at BEFORE UPDATE ON databooks_mestres
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- ============================================
-- ROW LEVEL SECURITY (RLS)
-- ============================================
ALTER TABLE usuarios ENABLE ROW LEVEL SECURITY;
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
ALTER TABLE templates_customizados ENABLE ROW LEVEL SECURITY;
ALTER TABLE projetos ENABLE ROW LEVEL SECURITY;
ALTER TABLE databooks_mestres ENABLE ROW LEVEL SECURITY;
ALTER TABLE secoes_databook ENABLE ROW LEVEL SECURITY;
ALTER TABLE configuracoes_pastas ENABLE ROW LEVEL SECURITY;
ALTER TABLE documentos_auto_indexados ENABLE ROW LEVEL SECURITY;
-- Policies básicas (ajustar conforme necessidade)
CREATE POLICY "Usuários podem ver todos os registros" ON usuarios FOR SELECT USING (true);
CREATE POLICY "Clientes podem ser vistos por todos" ON clientes FOR SELECT USING (true);
CREATE POLICY "Templates podem ser vistos por todos" ON templates_customizados FOR SELECT USING (true);
CREATE POLICY "Projetos podem ser vistos por todos" ON projetos FOR SELECT USING (true);
-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================
-- TABELA: USUARIOS
-- ============================================
CREATE TABLE usuarios (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) NOT NULL UNIQUE,
nome_completo VARCHAR(255) NOT NULL,
perfil VARCHAR(50) CHECK (perfil IN ('admin', 'gerente_qualidade', 'engenheiro', 'cliente')) DEFAULT 'engenheiro',
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_usuarios_email ON usuarios(email);
CREATE INDEX idx_usuarios_perfil ON usuarios(perfil);
-- ============================================
-- TABELA: CLIENTES
-- ============================================
CREATE TABLE clientes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(255) NOT NULL,
contato VARCHAR(255),
email VARCHAR(255),
telefone VARCHAR(20),
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_clientes_nome ON clientes(nome);
-- ============================================
-- TABELA: TEMPLATES_TOPICOS
-- ============================================
CREATE TABLE templates_topicos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
numero_topico VARCHAR(20) NOT NULL,
titulo VARCHAR(255) NOT NULL,
descricao TEXT,
obrigatorio BOOLEAN DEFAULT FALSE,
ordem INTEGER,
tipo_documentos TEXT[],
tags_padrao TEXT[],
categoria VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_topicos_numero ON templates_topicos(numero_topico);
CREATE INDEX idx_topicos_categoria ON templates_topicos(categoria);
-- ============================================
-- TABELA: TEMPLATES_CUSTOMIZADOS
-- ============================================
CREATE TABLE templates_customizados (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(255) NOT NULL UNIQUE,
tipo VARCHAR(50) CHECK (tipo IN ('novo', 'derivado')) DEFAULT 'novo',
template_pai_id UUID REFERENCES templates_customizados(id) ON DELETE SET NULL,
topicos_selecionados TEXT[],
total_topicos INTEGER,
total_obrigatorios INTEGER,
descricao TEXT,
ativo BOOLEAN DEFAULT TRUE,
criado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_templates_nome ON templates_customizados(nome);
CREATE INDEX idx_templates_tipo ON templates_customizados(tipo);
-- ============================================
-- TABELA: PROJETOS
-- ============================================
CREATE TABLE projetos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
numero_projeto VARCHAR(100) NOT NULL UNIQUE,
nome_projeto VARCHAR(255) NOT NULL,
cliente_id UUID REFERENCES clientes(id) ON DELETE CASCADE,
template_id UUID REFERENCES templates_customizados(id) ON DELETE SET NULL,
status VARCHAR(50) CHECK (status IN ('rascunho', 'em_andamento', 'revisao', 'finalizado', 'cancelado')) DEFAULT 'rascunho',
progresso_percentual INTEGER DEFAULT 0,
data_inicio DATE,
data_entrega_prevista DATE,
responsavel_id UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_projetos_numero ON projetos(numero_projeto);
CREATE INDEX idx_projetos_status ON projetos(status);
CREATE INDEX idx_projetos_cliente ON projetos(cliente_id);
-- ============================================
-- TABELA: DATABOOKS_MESTRES
-- ============================================
CREATE TABLE databooks_mestres (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
projeto_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
cliente_nome VARCHAR(255),
cliente_contato VARCHAR(255),
cliente_email VARCHAR(255),
cliente_telefone VARCHAR(20),
produto_nome VARCHAR(255) NOT NULL,
produto_tipo VARCHAR(100),
produto_descricao TEXT,
produto_normas TEXT[],
numero_projeto VARCHAR(100),
ordem_compra VARCHAR(100),
data_inicio DATE,
data_entrega_prevista DATE,
responsavel_id UUID,
revisao_numero VARCHAR(20) DEFAULT 'Rev. 0',
revisao_data TIMESTAMP DEFAULT NOW(),
revisao_autor_id UUID,
revisao_motivo TEXT,
logo_empresa_url TEXT,
logo_cliente_url TEXT,
marca_agua_url TEXT,
cor_primaria VARCHAR(7),
cor_secundaria VARCHAR(7),
titulo_principal VARCHAR(255),
subtitulo VARCHAR(255),
texto_rodape_capa TEXT,
tamanho_pagina VARCHAR(20) CHECK (tamanho_pagina IN ('A4', 'Letter')) DEFAULT 'A4',
orientacao VARCHAR(20) CHECK (orientacao IN ('retrato', 'paisagem')) DEFAULT 'retrato',
margem_superior_mm NUMERIC(5,2) DEFAULT 20,
margem_lateral_mm NUMERIC(5,2) DEFAULT 20,
incluir_marca_agua BOOLEAN DEFAULT TRUE,
incluir_numero_pagina BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_mestres_projeto ON databooks_mestres(projeto_id);
-- ============================================
-- TABELA: SECOES_DATABOOK
-- ============================================
CREATE TABLE secoes_databook (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
projeto_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
topico_id UUID REFERENCES templates_topicos(id),
numero_secao VARCHAR(20) NOT NULL,
titulo VARCHAR(255) NOT NULL,
ordem INTEGER,
status VARCHAR(50) CHECK (status IN ('completo', 'incompleto', 'nao_aplicavel')) DEFAULT 'incompleto',
total_documentos INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_secoes_projeto ON secoes_databook(projeto_id);
CREATE INDEX idx_secoes_numero ON secoes_databook(numero_secao);
-- ============================================
-- TABELA: CONFIGURACOES_PASTAS
-- ============================================
CREATE TABLE configuracoes_pastas (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tipo_documento VARCHAR(100) NOT NULL,
caminho_local TEXT NOT NULL,
caminho_subtipo VARCHAR(100),
caminho_completo TEXT,
habilitado BOOLEAN DEFAULT TRUE,
frequencia_atualizacao VARCHAR(50) CHECK (frequencia_atualizacao IN ('manual', 'ao_criar', 'diario', 'semanal')) DEFAULT 'ao_criar',
ultima_atualizacao TIMESTAMP,
incluir_subpastas BOOLEAN DEFAULT TRUE,
formatos_aceitos TEXT[],
tamanho_maximo_mb INTEGER DEFAULT 50,
tags_obrigatorias TEXT[],
palavras_chave_filtro TEXT[],
palavras_chave_excluir TEXT[],
ordem_docs VARCHAR(50) CHECK (ordem_docs IN ('data', 'nome', 'relevancia')) DEFAULT 'data',
criado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_pastas_tipo ON configuracoes_pastas(tipo_documento);
-- ============================================
-- TABELA: INTEGRACAO_IA
-- ============================================
CREATE TABLE integracao_ia (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
provider VARCHAR(50) CHECK (provider IN ('openai', 'claude', 'gemini')) NOT NULL,
api_key_encriptada TEXT NOT NULL,
modelo_padrao VARCHAR(100),
maximo_tokens INTEGER DEFAULT 2000,
ativo BOOLEAN DEFAULT FALSE,
testado_em TIMESTAMP,
teste_status VARCHAR(50),
teste_mensagem TEXT,
criado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- ============================================
-- TABELA: DOCUMENTOS_AUTO_INDEXADOS
-- ============================================
CREATE TABLE documentos_auto_indexados (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
databook_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
secao_id UUID REFERENCES secoes_databook(id) ON DELETE SET NULL,
secao_numero VARCHAR(20),
titulo VARCHAR(255) NOT NULL,
numero_documento VARCHAR(100),
revisao VARCHAR(20),
arquivo_url TEXT NOT NULL,
arquivo_tipo VARCHAR(50),
conteudo_texto TEXT,
tags_automaticas TEXT[],
tags_usuario TEXT[],
relevancia_score NUMERIC(3,2),
confianca_classificacao NUMERIC(3,2),
ordem_na_secao INTEGER,
data_documento DATE,
aprovado BOOLEAN DEFAULT FALSE,
processado_por_ia VARCHAR(50),
processado_em TIMESTAMP,
criado_em TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_auto_databook ON documentos_auto_indexados(databook_id);
CREATE INDEX idx_auto_secao ON documentos_auto_indexados(secao_numero);
-- ============================================
-- TABELA: LOG_PROCESSAMENTO_IA
-- ============================================
CREATE TABLE log_processamento_ia (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
databook_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
inicio_processamento TIMESTAMP,
fim_processamento TIMESTAMP,
duracao_segundos INTEGER,
total_documentos_encontrados INTEGER,
total_documentos_indexados INTEGER,
total_erros INTEGER,
pastas_varridas TEXT[],
provider_ia VARCHAR(50),
modelo_usado VARCHAR(100),
tokens_utilizados INTEGER,
status VARCHAR(50) CHECK (status IN ('sucesso', 'parcial', 'erro')) DEFAULT 'sucesso',
mensagem_erro TEXT,
iniciado_por UUID REFERENCES usuarios(id),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_log_ia_databook ON log_processamento_ia(databook_id);
-- ============================================
-- TABELA: PERMISSOES_USUARIO_DETALHADAS
-- ============================================
CREATE TABLE permissoes_usuario_detalhadas (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
usuario_id UUID NOT NULL REFERENCES usuarios(id) ON DELETE CASCADE,
pode_criar_template BOOLEAN DEFAULT FALSE,
pode_editar_template BOOLEAN DEFAULT FALSE,
pode_deletar_template BOOLEAN DEFAULT FALSE,
pode_criar_databook BOOLEAN DEFAULT FALSE,
pode_editar_databook BOOLEAN DEFAULT FALSE,
pode_deletar_databook BOOLEAN DEFAULT FALSE,
pode_upload_documentos BOOLEAN DEFAULT FALSE,
pode_aprovar_documentos BOOLEAN DEFAULT FALSE,
pode_gerar_pdf BOOLEAN DEFAULT FALSE,
pode_visualizar_preview BOOLEAN DEFAULT FALSE,
pode_acessar_logs BOOLEAN DEFAULT FALSE,
pode_configurar_ia BOOLEAN DEFAULT FALSE,
pode_configurar_pastas BOOLEAN DEFAULT FALSE,
pode_gerenciar_usuarios BOOLEAN DEFAULT FALSE,
acesso_apenas_seus_projetos BOOLEAN DEFAULT TRUE,
pode_visualizar_precos BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(usuario_id)
);
-- ============================================
-- VIEWS
-- ============================================
CREATE OR REPLACE VIEW view_projetos_resumo AS
SELECT
p.id,
p.numero_projeto,
p.nome_projeto,
p.status,
p.progresso_percentual,
c.nome as cliente_nome,
tc.nome as template_nome,
COUNT(DISTINCT sd.id) as total_secoes,
COUNT(DISTINCT dai.id) as total_documentos,
p.created_at
FROM projetos p
LEFT JOIN clientes c ON p.cliente_id = c.id
LEFT JOIN templates_customizados tc ON p.template_id = tc.id
LEFT JOIN secoes_databook sd ON p.id = sd.projeto_id
LEFT JOIN documentos_auto_indexados dai ON p.id = dai.databook_id
GROUP BY p.id, c.nome, tc.nome
ORDER BY p.created_at DESC;
-- ============================================
-- TRIGGERS
-- ============================================
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_templates_updated_at BEFORE UPDATE ON templates_customizados
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_projetos_updated_at BEFORE UPDATE ON projetos
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_databooks_mestres_updated_at BEFORE UPDATE ON databooks_mestres
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- ============================================
-- ROW LEVEL SECURITY (RLS)
-- ============================================
ALTER TABLE usuarios ENABLE ROW LEVEL SECURITY;
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
ALTER TABLE templates_customizados ENABLE ROW LEVEL SECURITY;
ALTER TABLE projetos ENABLE ROW LEVEL SECURITY;
ALTER TABLE databooks_mestres ENABLE ROW LEVEL SECURITY;
ALTER TABLE secoes_databook ENABLE ROW LEVEL SECURITY;
ALTER TABLE configuracoes_pastas ENABLE ROW LEVEL SECURITY;
ALTER TABLE documentos_auto_indexados ENABLE ROW LEVEL SECURITY;
-- Policies básicas (ajustar conforme necessidade)
CREATE POLICY "Usuários podem ver todos os registros" ON usuarios FOR SELECT USING (true);
CREATE POLICY "Clientes podem ser vistos por todos" ON clientes FOR SELECT USING (true);
CREATE POLICY "Templates podem ser vistos por todos" ON templates_customizados FOR SELECT USING (true);
CREATE POLICY "Projetos podem ser vistos por todos" ON projetos FOR SELECT USING (true);

View File

@@ -1,105 +1,105 @@
-- Fix RLS policies to allow INSERT, UPDATE, DELETE operations
-- Templates policies
DROP POLICY IF EXISTS "Templates podem ser vistos por todos" ON templates_customizados;
CREATE POLICY "Templates - SELECT para todos" ON templates_customizados
FOR SELECT USING (true);
CREATE POLICY "Templates - INSERT para usuários autenticados" ON templates_customizados
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Templates - UPDATE para usuários autenticados" ON templates_customizados
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Templates - DELETE para usuários autenticados" ON templates_customizados
FOR DELETE USING (auth.role() = 'authenticated');
-- Clientes policies
DROP POLICY IF EXISTS "Clientes podem ser vistos por todos" ON clientes;
CREATE POLICY "Clientes - SELECT para todos" ON clientes
FOR SELECT USING (true);
CREATE POLICY "Clientes - INSERT para usuários autenticados" ON clientes
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Clientes - UPDATE para usuários autenticados" ON clientes
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Clientes - DELETE para usuários autenticados" ON clientes
FOR DELETE USING (auth.role() = 'authenticated');
-- Projetos policies
DROP POLICY IF EXISTS "Projetos podem ser vistos por todos" ON projetos;
CREATE POLICY "Projetos - SELECT para todos" ON projetos
FOR SELECT USING (true);
CREATE POLICY "Projetos - INSERT para usuários autenticados" ON projetos
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Projetos - UPDATE para usuários autenticados" ON projetos
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Projetos - DELETE para usuários autenticados" ON projetos
FOR DELETE USING (auth.role() = 'authenticated');
-- Databooks policies
CREATE POLICY "Databooks - SELECT para todos" ON databooks_mestres
FOR SELECT USING (true);
CREATE POLICY "Databooks - INSERT para usuários autenticados" ON databooks_mestres
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Databooks - UPDATE para usuários autenticados" ON databooks_mestres
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Databooks - DELETE para usuários autenticados" ON databooks_mestres
FOR DELETE USING (auth.role() = 'authenticated');
-- Secoes policies
CREATE POLICY "Secoes - SELECT para todos" ON secoes_databook
FOR SELECT USING (true);
CREATE POLICY "Secoes - INSERT para usuários autenticados" ON secoes_databook
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Secoes - UPDATE para usuários autenticados" ON secoes_databook
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Secoes - DELETE para usuários autenticados" ON secoes_databook
FOR DELETE USING (auth.role() = 'authenticated');
-- Configuracoes_pastas policies
CREATE POLICY "Pastas - SELECT para todos" ON configuracoes_pastas
FOR SELECT USING (true);
CREATE POLICY "Pastas - INSERT para usuários autenticados" ON configuracoes_pastas
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Pastas - UPDATE para usuários autenticados" ON configuracoes_pastas
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Pastas - DELETE para usuários autenticados" ON configuracoes_pastas
FOR DELETE USING (auth.role() = 'authenticated');
-- Documentos_auto_indexados policies
CREATE POLICY "Documentos - SELECT para todos" ON documentos_auto_indexados
FOR SELECT USING (true);
CREATE POLICY "Documentos - INSERT para usuários autenticados" ON documentos_auto_indexados
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Documentos - UPDATE para usuários autenticados" ON documentos_auto_indexados
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Documentos - DELETE para usuários autenticados" ON documentos_auto_indexados
FOR DELETE USING (auth.role() = 'authenticated');
-- Fix RLS policies to allow INSERT, UPDATE, DELETE operations
-- Templates policies
DROP POLICY IF EXISTS "Templates podem ser vistos por todos" ON templates_customizados;
CREATE POLICY "Templates - SELECT para todos" ON templates_customizados
FOR SELECT USING (true);
CREATE POLICY "Templates - INSERT para usuários autenticados" ON templates_customizados
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Templates - UPDATE para usuários autenticados" ON templates_customizados
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Templates - DELETE para usuários autenticados" ON templates_customizados
FOR DELETE USING (auth.role() = 'authenticated');
-- Clientes policies
DROP POLICY IF EXISTS "Clientes podem ser vistos por todos" ON clientes;
CREATE POLICY "Clientes - SELECT para todos" ON clientes
FOR SELECT USING (true);
CREATE POLICY "Clientes - INSERT para usuários autenticados" ON clientes
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Clientes - UPDATE para usuários autenticados" ON clientes
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Clientes - DELETE para usuários autenticados" ON clientes
FOR DELETE USING (auth.role() = 'authenticated');
-- Projetos policies
DROP POLICY IF EXISTS "Projetos podem ser vistos por todos" ON projetos;
CREATE POLICY "Projetos - SELECT para todos" ON projetos
FOR SELECT USING (true);
CREATE POLICY "Projetos - INSERT para usuários autenticados" ON projetos
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Projetos - UPDATE para usuários autenticados" ON projetos
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Projetos - DELETE para usuários autenticados" ON projetos
FOR DELETE USING (auth.role() = 'authenticated');
-- Databooks policies
CREATE POLICY "Databooks - SELECT para todos" ON databooks_mestres
FOR SELECT USING (true);
CREATE POLICY "Databooks - INSERT para usuários autenticados" ON databooks_mestres
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Databooks - UPDATE para usuários autenticados" ON databooks_mestres
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Databooks - DELETE para usuários autenticados" ON databooks_mestres
FOR DELETE USING (auth.role() = 'authenticated');
-- Secoes policies
CREATE POLICY "Secoes - SELECT para todos" ON secoes_databook
FOR SELECT USING (true);
CREATE POLICY "Secoes - INSERT para usuários autenticados" ON secoes_databook
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Secoes - UPDATE para usuários autenticados" ON secoes_databook
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Secoes - DELETE para usuários autenticados" ON secoes_databook
FOR DELETE USING (auth.role() = 'authenticated');
-- Configuracoes_pastas policies
CREATE POLICY "Pastas - SELECT para todos" ON configuracoes_pastas
FOR SELECT USING (true);
CREATE POLICY "Pastas - INSERT para usuários autenticados" ON configuracoes_pastas
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Pastas - UPDATE para usuários autenticados" ON configuracoes_pastas
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Pastas - DELETE para usuários autenticados" ON configuracoes_pastas
FOR DELETE USING (auth.role() = 'authenticated');
-- Documentos_auto_indexados policies
CREATE POLICY "Documentos - SELECT para todos" ON documentos_auto_indexados
FOR SELECT USING (true);
CREATE POLICY "Documentos - INSERT para usuários autenticados" ON documentos_auto_indexados
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Documentos - UPDATE para usuários autenticados" ON documentos_auto_indexados
FOR UPDATE USING (auth.role() = 'authenticated')
WITH CHECK (auth.role() = 'authenticated');
CREATE POLICY "Documentos - DELETE para usuários autenticados" ON documentos_auto_indexados
FOR DELETE USING (auth.role() = 'authenticated');

View File

@@ -1,7 +1,7 @@
-- Adicionar tipo 'padrao' aos templates
ALTER TABLE templates_customizados
DROP CONSTRAINT IF EXISTS templates_customizados_tipo_check;
ALTER TABLE templates_customizados
ADD CONSTRAINT templates_customizados_tipo_check
CHECK (tipo IN ('novo', 'derivado', 'padrao'));
-- Adicionar tipo 'padrao' aos templates
ALTER TABLE templates_customizados
DROP CONSTRAINT IF EXISTS templates_customizados_tipo_check;
ALTER TABLE templates_customizados
ADD CONSTRAINT templates_customizados_tipo_check
CHECK (tipo IN ('novo', 'derivado', 'padrao'));

View File

@@ -1,3 +1,3 @@
-- Alterar coluna arquivo_url para TEXT para suportar base64
ALTER TABLE documentos_auto_indexados
ALTER COLUMN arquivo_url TYPE TEXT;
-- Alterar coluna arquivo_url para TEXT para suportar base64
ALTER TABLE documentos_auto_indexados
ALTER COLUMN arquivo_url TYPE TEXT;

View File

@@ -1,30 +1,30 @@
-- Criar tabela de categorias
CREATE TABLE IF NOT EXISTS categorias (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(100) NOT NULL UNIQUE,
descricao TEXT,
cor VARCHAR(7) DEFAULT '#3B82F6',
icone VARCHAR(50),
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Desabilitar RLS para desenvolvimento
ALTER TABLE categorias DISABLE ROW LEVEL SECURITY;
-- Inserir categorias padrão
INSERT INTO categorias (nome, descricao, cor) VALUES
('Certificados', 'Certificados de qualificação e conformidade', '#10B981'),
('Desenhos', 'Desenhos técnicos e de fabricação', '#3B82F6'),
('Relatórios', 'Relatórios de inspeção e testes', '#F59E0B'),
('Procedimentos', 'Procedimentos e instruções', '#8B5CF6'),
('Normas', 'Normas e especificações técnicas', '#EF4444')
ON CONFLICT (nome) DO NOTHING;
-- Adicionar coluna categoria_id nas tabelas existentes
ALTER TABLE templates_topicos
ADD COLUMN IF NOT EXISTS categoria_id UUID REFERENCES categorias(id) ON DELETE SET NULL;
ALTER TABLE configuracoes_pastas
ADD COLUMN IF NOT EXISTS categoria_id UUID REFERENCES categorias(id) ON DELETE SET NULL;
-- Criar tabela de categorias
CREATE TABLE IF NOT EXISTS categorias (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(100) NOT NULL UNIQUE,
descricao TEXT,
cor VARCHAR(7) DEFAULT '#3B82F6',
icone VARCHAR(50),
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Desabilitar RLS para desenvolvimento
ALTER TABLE categorias DISABLE ROW LEVEL SECURITY;
-- Inserir categorias padrão
INSERT INTO categorias (nome, descricao, cor) VALUES
('Certificados', 'Certificados de qualificação e conformidade', '#10B981'),
('Desenhos', 'Desenhos técnicos e de fabricação', '#3B82F6'),
('Relatórios', 'Relatórios de inspeção e testes', '#F59E0B'),
('Procedimentos', 'Procedimentos e instruções', '#8B5CF6'),
('Normas', 'Normas e especificações técnicas', '#EF4444')
ON CONFLICT (nome) DO NOTHING;
-- Adicionar coluna categoria_id nas tabelas existentes
ALTER TABLE templates_topicos
ADD COLUMN IF NOT EXISTS categoria_id UUID REFERENCES categorias(id) ON DELETE SET NULL;
ALTER TABLE configuracoes_pastas
ADD COLUMN IF NOT EXISTS categoria_id UUID REFERENCES categorias(id) ON DELETE SET NULL;

View File

@@ -1,162 +1,162 @@
-- Criar tabela de templates de design
CREATE TABLE IF NOT EXISTS design_templates (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(255) NOT NULL,
descricao TEXT,
tipo VARCHAR(50) NOT NULL CHECK (tipo IN ('capa', 'indice', 'divisora', 'cabecalho', 'rodape', 'guia_estilo')),
config JSONB NOT NULL DEFAULT '{}',
ativo BOOLEAN DEFAULT TRUE,
criado_por UUID REFERENCES auth.users(id) ON DELETE SET NULL,
criado_em TIMESTAMP DEFAULT NOW(),
atualizado_em TIMESTAMP DEFAULT NOW(),
UNIQUE(nome)
);
-- Criar índices
CREATE INDEX idx_design_templates_tipo ON design_templates(tipo);
CREATE INDEX idx_design_templates_ativo ON design_templates(ativo);
CREATE INDEX idx_design_templates_criado_por ON design_templates(criado_por);
-- Desabilitar RLS para desenvolvimento
ALTER TABLE design_templates DISABLE ROW LEVEL SECURITY;
-- Inserir templates padrão
INSERT INTO design_templates (nome, descricao, tipo, config) VALUES
(
'Capa Padrão',
'Template padrão para capa frontal do databook',
'capa',
'{
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"titulo": "BUZIOS 7 PRODUCTION SYSTEM DEVELOPMENT",
"subtitulo": "AR HEAD FABRICATION LONG",
"cliente": "SAIPEM",
"numeroDocumento": "DB-B97-01_S1_VENDOR_DATABOOK",
"contrato": "OC 1472739",
"fornecedor": "ENGEMETAL"
}'
),
(
'Índice Bilíngue',
'Template de índice com suporte a português e inglês',
'indice',
'{
"corTitulo": "#1a365d",
"corLinha": "#2b6cb0",
"bilingue": true,
"titulo": "ÍNDICE / TABLE OF CONTENTS"
}'
),
(
'Divisora Minimalista',
'Template minimalista para divisoras de seção',
'divisora',
'{
"estilo": "minimalista",
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"bilingue": true,
"icone": "📑"
}'
),
(
'Divisora Lateral',
'Template com barra lateral para divisoras',
'divisora',
'{
"estilo": "lateral",
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"bilingue": true,
"icone": "📑"
}'
),
(
'Divisora Corporativa',
'Template corporativo para divisoras',
'divisora',
'{
"estilo": "corporativa",
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"bilingue": true,
"icone": "📑"
}'
),
(
'Cabeçalho Padrão',
'Template padrão para cabeçalho de página',
'cabecalho',
'{
"corBorda": "#2b6cb0",
"altura": 60,
"estilo": "simples"
}'
),
(
'Rodapé Padrão',
'Template padrão para rodapé de página',
'rodape',
'{
"corBorda": "#cbd5e0",
"altura": 40,
"estilo": "simples",
"mostrarPagina": true
}'
),
(
'Guia de Estilo Padrão',
'Template de guia de estilo completo',
'guia_estilo',
'{
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"corDestaque": "#4299e1",
"fontePrincipal": "Roboto",
"fonteSecundaria": "Open Sans",
"incluirPaleta": true,
"incluirTipografia": true
}'
)
ON CONFLICT (nome) DO NOTHING;
-- Criar tabela de aplicação de templates a databooks
CREATE TABLE IF NOT EXISTS databook_design_aplicacoes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
databook_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
template_capa_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_indice_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_divisora_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_cabecalho_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_rodape_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_guia_estilo_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
aplicado_em TIMESTAMP DEFAULT NOW(),
atualizado_em TIMESTAMP DEFAULT NOW(),
UNIQUE(databook_id)
);
-- Criar índices
CREATE INDEX idx_databook_design_aplicacoes_databook ON databook_design_aplicacoes(databook_id);
-- Desabilitar RLS
ALTER TABLE databook_design_aplicacoes DISABLE ROW LEVEL SECURITY;
-- Criar trigger para atualizar atualizado_em
CREATE OR REPLACE FUNCTION update_design_templates_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.atualizado_em = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_design_templates_updated_at_trigger
BEFORE UPDATE ON design_templates
FOR EACH ROW
EXECUTE FUNCTION update_design_templates_updated_at();
CREATE TRIGGER update_databook_design_aplicacoes_updated_at_trigger
BEFORE UPDATE ON databook_design_aplicacoes
FOR EACH ROW
EXECUTE FUNCTION update_design_templates_updated_at();
-- Criar tabela de templates de design
CREATE TABLE IF NOT EXISTS design_templates (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(255) NOT NULL,
descricao TEXT,
tipo VARCHAR(50) NOT NULL CHECK (tipo IN ('capa', 'indice', 'divisora', 'cabecalho', 'rodape', 'guia_estilo')),
config JSONB NOT NULL DEFAULT '{}',
ativo BOOLEAN DEFAULT TRUE,
criado_por UUID REFERENCES auth.users(id) ON DELETE SET NULL,
criado_em TIMESTAMP DEFAULT NOW(),
atualizado_em TIMESTAMP DEFAULT NOW(),
UNIQUE(nome)
);
-- Criar índices
CREATE INDEX idx_design_templates_tipo ON design_templates(tipo);
CREATE INDEX idx_design_templates_ativo ON design_templates(ativo);
CREATE INDEX idx_design_templates_criado_por ON design_templates(criado_por);
-- Desabilitar RLS para desenvolvimento
ALTER TABLE design_templates DISABLE ROW LEVEL SECURITY;
-- Inserir templates padrão
INSERT INTO design_templates (nome, descricao, tipo, config) VALUES
(
'Capa Padrão',
'Template padrão para capa frontal do databook',
'capa',
'{
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"titulo": "BUZIOS 7 PRODUCTION SYSTEM DEVELOPMENT",
"subtitulo": "AR HEAD FABRICATION LONG",
"cliente": "SAIPEM",
"numeroDocumento": "DB-B97-01_S1_VENDOR_DATABOOK",
"contrato": "OC 1472739",
"fornecedor": "ENGEMETAL"
}'
),
(
'Índice Bilíngue',
'Template de índice com suporte a português e inglês',
'indice',
'{
"corTitulo": "#1a365d",
"corLinha": "#2b6cb0",
"bilingue": true,
"titulo": "ÍNDICE / TABLE OF CONTENTS"
}'
),
(
'Divisora Minimalista',
'Template minimalista para divisoras de seção',
'divisora',
'{
"estilo": "minimalista",
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"bilingue": true,
"icone": "📑"
}'
),
(
'Divisora Lateral',
'Template com barra lateral para divisoras',
'divisora',
'{
"estilo": "lateral",
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"bilingue": true,
"icone": "📑"
}'
),
(
'Divisora Corporativa',
'Template corporativo para divisoras',
'divisora',
'{
"estilo": "corporativa",
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"bilingue": true,
"icone": "📑"
}'
),
(
'Cabeçalho Padrão',
'Template padrão para cabeçalho de página',
'cabecalho',
'{
"corBorda": "#2b6cb0",
"altura": 60,
"estilo": "simples"
}'
),
(
'Rodapé Padrão',
'Template padrão para rodapé de página',
'rodape',
'{
"corBorda": "#cbd5e0",
"altura": 40,
"estilo": "simples",
"mostrarPagina": true
}'
),
(
'Guia de Estilo Padrão',
'Template de guia de estilo completo',
'guia_estilo',
'{
"corPrimaria": "#1a365d",
"corSecundaria": "#2b6cb0",
"corDestaque": "#4299e1",
"fontePrincipal": "Roboto",
"fonteSecundaria": "Open Sans",
"incluirPaleta": true,
"incluirTipografia": true
}'
)
ON CONFLICT (nome) DO NOTHING;
-- Criar tabela de aplicação de templates a databooks
CREATE TABLE IF NOT EXISTS databook_design_aplicacoes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
databook_id UUID NOT NULL REFERENCES projetos(id) ON DELETE CASCADE,
template_capa_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_indice_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_divisora_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_cabecalho_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_rodape_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
template_guia_estilo_id UUID REFERENCES design_templates(id) ON DELETE SET NULL,
aplicado_em TIMESTAMP DEFAULT NOW(),
atualizado_em TIMESTAMP DEFAULT NOW(),
UNIQUE(databook_id)
);
-- Criar índices
CREATE INDEX idx_databook_design_aplicacoes_databook ON databook_design_aplicacoes(databook_id);
-- Desabilitar RLS
ALTER TABLE databook_design_aplicacoes DISABLE ROW LEVEL SECURITY;
-- Criar trigger para atualizar atualizado_em
CREATE OR REPLACE FUNCTION update_design_templates_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.atualizado_em = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_design_templates_updated_at_trigger
BEFORE UPDATE ON design_templates
FOR EACH ROW
EXECUTE FUNCTION update_design_templates_updated_at();
CREATE TRIGGER update_databook_design_aplicacoes_updated_at_trigger
BEFORE UPDATE ON databook_design_aplicacoes
FOR EACH ROW
EXECUTE FUNCTION update_design_templates_updated_at();

View File

@@ -1,58 +1,58 @@
-- Adicionar status 'arquivado' aos projetos
ALTER TABLE projetos DROP CONSTRAINT IF EXISTS projetos_status_check;
ALTER TABLE projetos ADD CONSTRAINT projetos_status_check
CHECK (status IN ('rascunho', 'em_andamento', 'revisao', 'finalizado', 'cancelado', 'arquivado'));
-- Adicionar campo 'ativo' à tabela templates_topicos (soft delete)
ALTER TABLE templates_topicos ADD COLUMN IF NOT EXISTS ativo BOOLEAN DEFAULT TRUE;
CREATE INDEX IF NOT EXISTS idx_topicos_ativo ON templates_topicos(ativo);
-- Adicionar campo 'inativado_em' para rastreamento
ALTER TABLE templates_topicos ADD COLUMN IF NOT EXISTS inativado_em TIMESTAMP;
ALTER TABLE templates_customizados ADD COLUMN IF NOT EXISTS inativado_em TIMESTAMP;
-- Comentários explicativos
COMMENT ON COLUMN templates_topicos.ativo IS 'Soft delete: FALSE oculta o tópico de novas criações mas mantém em databooks existentes';
COMMENT ON COLUMN templates_customizados.ativo IS 'Soft delete: FALSE oculta o template de novas criações mas mantém em databooks existentes';
-- Criar função para "soft delete" de templates
CREATE OR REPLACE FUNCTION soft_delete_template()
RETURNS TRIGGER AS $$
BEGIN
-- Ao invés de deletar, marca como inativo
UPDATE templates_customizados
SET ativo = FALSE, inativado_em = NOW()
WHERE id = OLD.id;
-- Impede a exclusão física
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- Criar trigger para soft delete de templates
DROP TRIGGER IF EXISTS prevent_template_hard_delete ON templates_customizados;
CREATE TRIGGER prevent_template_hard_delete
BEFORE DELETE ON templates_customizados
FOR EACH ROW
EXECUTE FUNCTION soft_delete_template();
-- Criar função para "soft delete" de tópicos
CREATE OR REPLACE FUNCTION soft_delete_topico()
RETURNS TRIGGER AS $$
BEGIN
-- Ao invés de deletar, marca como inativo
UPDATE templates_topicos
SET ativo = FALSE, inativado_em = NOW()
WHERE id = OLD.id;
-- Impede a exclusão física
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- Criar trigger para soft delete de tópicos
DROP TRIGGER IF EXISTS prevent_topico_hard_delete ON templates_topicos;
CREATE TRIGGER prevent_topico_hard_delete
BEFORE DELETE ON templates_topicos
FOR EACH ROW
EXECUTE FUNCTION soft_delete_topico();
-- Adicionar status 'arquivado' aos projetos
ALTER TABLE projetos DROP CONSTRAINT IF EXISTS projetos_status_check;
ALTER TABLE projetos ADD CONSTRAINT projetos_status_check
CHECK (status IN ('rascunho', 'em_andamento', 'revisao', 'finalizado', 'cancelado', 'arquivado'));
-- Adicionar campo 'ativo' à tabela templates_topicos (soft delete)
ALTER TABLE templates_topicos ADD COLUMN IF NOT EXISTS ativo BOOLEAN DEFAULT TRUE;
CREATE INDEX IF NOT EXISTS idx_topicos_ativo ON templates_topicos(ativo);
-- Adicionar campo 'inativado_em' para rastreamento
ALTER TABLE templates_topicos ADD COLUMN IF NOT EXISTS inativado_em TIMESTAMP;
ALTER TABLE templates_customizados ADD COLUMN IF NOT EXISTS inativado_em TIMESTAMP;
-- Comentários explicativos
COMMENT ON COLUMN templates_topicos.ativo IS 'Soft delete: FALSE oculta o tópico de novas criações mas mantém em databooks existentes';
COMMENT ON COLUMN templates_customizados.ativo IS 'Soft delete: FALSE oculta o template de novas criações mas mantém em databooks existentes';
-- Criar função para "soft delete" de templates
CREATE OR REPLACE FUNCTION soft_delete_template()
RETURNS TRIGGER AS $$
BEGIN
-- Ao invés de deletar, marca como inativo
UPDATE templates_customizados
SET ativo = FALSE, inativado_em = NOW()
WHERE id = OLD.id;
-- Impede a exclusão física
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- Criar trigger para soft delete de templates
DROP TRIGGER IF EXISTS prevent_template_hard_delete ON templates_customizados;
CREATE TRIGGER prevent_template_hard_delete
BEFORE DELETE ON templates_customizados
FOR EACH ROW
EXECUTE FUNCTION soft_delete_template();
-- Criar função para "soft delete" de tópicos
CREATE OR REPLACE FUNCTION soft_delete_topico()
RETURNS TRIGGER AS $$
BEGIN
-- Ao invés de deletar, marca como inativo
UPDATE templates_topicos
SET ativo = FALSE, inativado_em = NOW()
WHERE id = OLD.id;
-- Impede a exclusão física
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- Criar trigger para soft delete de tópicos
DROP TRIGGER IF EXISTS prevent_topico_hard_delete ON templates_topicos;
CREATE TRIGGER prevent_topico_hard_delete
BEFORE DELETE ON templates_topicos
FOR EACH ROW
EXECUTE FUNCTION soft_delete_topico();

View File

@@ -1,20 +1,20 @@
-- Adicionar campos de metadados aos documentos
ALTER TABLE documentos_auto_indexados
ADD COLUMN IF NOT EXISTS arquivo_tamanho BIGINT,
ADD COLUMN IF NOT EXISTS num_paginas INTEGER DEFAULT 1,
ADD COLUMN IF NOT EXISTS formato_pagina VARCHAR(20) DEFAULT 'A4',
ADD COLUMN IF NOT EXISTS orientacao VARCHAR(20) DEFAULT 'retrato';
-- Comentários explicativos
COMMENT ON COLUMN documentos_auto_indexados.arquivo_tamanho IS 'Tamanho do arquivo em bytes';
COMMENT ON COLUMN documentos_auto_indexados.num_paginas IS 'Número de páginas do documento';
COMMENT ON COLUMN documentos_auto_indexados.formato_pagina IS 'Formato da página: A4, A3, A2, A1, etc';
COMMENT ON COLUMN documentos_auto_indexados.orientacao IS 'Orientação: retrato ou paisagem';
-- Atualizar documentos existentes com valores padrão
UPDATE documentos_auto_indexados
SET
num_paginas = 1,
formato_pagina = 'A4',
orientacao = 'retrato'
WHERE num_paginas IS NULL;
-- Adicionar campos de metadados aos documentos
ALTER TABLE documentos_auto_indexados
ADD COLUMN IF NOT EXISTS arquivo_tamanho BIGINT,
ADD COLUMN IF NOT EXISTS num_paginas INTEGER DEFAULT 1,
ADD COLUMN IF NOT EXISTS formato_pagina VARCHAR(20) DEFAULT 'A4',
ADD COLUMN IF NOT EXISTS orientacao VARCHAR(20) DEFAULT 'retrato';
-- Comentários explicativos
COMMENT ON COLUMN documentos_auto_indexados.arquivo_tamanho IS 'Tamanho do arquivo em bytes';
COMMENT ON COLUMN documentos_auto_indexados.num_paginas IS 'Número de páginas do documento';
COMMENT ON COLUMN documentos_auto_indexados.formato_pagina IS 'Formato da página: A4, A3, A2, A1, etc';
COMMENT ON COLUMN documentos_auto_indexados.orientacao IS 'Orientação: retrato ou paisagem';
-- Atualizar documentos existentes com valores padrão
UPDATE documentos_auto_indexados
SET
num_paginas = 1,
formato_pagina = 'A4',
orientacao = 'retrato'
WHERE num_paginas IS NULL;