441 lines
17 KiB
SQL
441 lines
17 KiB
SQL
-- ============================================================
|
|
-- SCHEMA NORMALIZADO PARA O EDUMANAGER SELF-HOSTED
|
|
-- PostgreSQL 15
|
|
-- Baseado nas interfaces TypeScript do types.ts
|
|
-- ============================================================
|
|
|
|
-- Extensão para gerar UUIDs
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
-- ============================================================
|
|
-- 1. PERFIL DA ESCOLA (Configurações Gerais)
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS configuracoes (
|
|
id TEXT PRIMARY KEY DEFAULT 'main-school',
|
|
nome TEXT NOT NULL DEFAULT 'EduManager School',
|
|
endereco TEXT DEFAULT '',
|
|
cidade TEXT DEFAULT '',
|
|
estado TEXT DEFAULT '',
|
|
cep TEXT DEFAULT '',
|
|
cnpj TEXT DEFAULT '',
|
|
telefone TEXT DEFAULT '',
|
|
email TEXT DEFAULT '',
|
|
tipo TEXT DEFAULT 'matriz' CHECK (tipo IN ('matriz', 'filial')),
|
|
logo TEXT DEFAULT '',
|
|
-- Configurações do Evolution API (WhatsApp)
|
|
evolution_api_url TEXT,
|
|
evolution_instance_name TEXT,
|
|
evolution_api_key TEXT,
|
|
-- Templates de mensagens (JSON)
|
|
message_templates JSONB DEFAULT '{}',
|
|
-- Timestamp
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 2. USUÁRIOS DO PAINEL ADMINISTRATIVO
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS usuarios (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
username TEXT NOT NULL UNIQUE,
|
|
display_name TEXT,
|
|
photo_url TEXT,
|
|
password TEXT NOT NULL,
|
|
cpf TEXT DEFAULT '',
|
|
role TEXT DEFAULT 'admin' CHECK (role IN ('admin', 'user')),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Admin padrão
|
|
INSERT INTO usuarios (id, username, display_name, password, cpf, role)
|
|
VALUES ('default-admin', 'admin', 'Administrador', 'admin', '000.000.000-00', 'admin')
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
|
-- ============================================================
|
|
-- 3. CURSOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS cursos (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
duracao TEXT DEFAULT '',
|
|
duracao_meses INTEGER DEFAULT 0,
|
|
taxa_matricula NUMERIC(10,2) DEFAULT 0,
|
|
mensalidade NUMERIC(10,2) DEFAULT 0,
|
|
descricao TEXT DEFAULT '',
|
|
multa_percentual NUMERIC(5,2) DEFAULT 0,
|
|
juros_percentual NUMERIC(5,2) DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 4. TURMAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS turmas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
curso_id TEXT REFERENCES cursos(id) ON DELETE SET NULL,
|
|
professor TEXT DEFAULT '',
|
|
horario TEXT DEFAULT '',
|
|
dia_semana TEXT,
|
|
max_alunos INTEGER DEFAULT 30,
|
|
data_inicio DATE,
|
|
data_fim DATE,
|
|
horario_inicio_padrao TEXT,
|
|
horario_fim_padrao TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 5. ALUNOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS alunos (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
email TEXT DEFAULT '',
|
|
telefone TEXT DEFAULT '',
|
|
data_nascimento DATE,
|
|
cpf TEXT DEFAULT '',
|
|
rg TEXT,
|
|
rg_data_emissao DATE,
|
|
nome_responsavel TEXT,
|
|
telefone_responsavel TEXT,
|
|
cpf_responsavel TEXT,
|
|
data_nascimento_responsavel DATE,
|
|
turma_id TEXT REFERENCES turmas(id) ON DELETE SET NULL,
|
|
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'cancelled')),
|
|
motivo_cancelamento TEXT,
|
|
data_matricula DATE DEFAULT CURRENT_DATE,
|
|
foto_url TEXT,
|
|
face_descriptor JSONB,
|
|
-- Endereço
|
|
cep TEXT DEFAULT '',
|
|
rua TEXT DEFAULT '',
|
|
numero TEXT DEFAULT '',
|
|
bairro TEXT DEFAULT '',
|
|
cidade TEXT DEFAULT '',
|
|
estado TEXT DEFAULT '',
|
|
-- Financeiro
|
|
desconto NUMERIC(10,2) DEFAULT 0,
|
|
tem_responsavel BOOLEAN DEFAULT FALSE,
|
|
modelo_contrato_id TEXT,
|
|
-- Portal do Aluno
|
|
numero_matricula TEXT UNIQUE,
|
|
senha_portal TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 6. AULAS / CRONOGRAMA
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS aulas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
turma_id TEXT NOT NULL REFERENCES turmas(id) ON DELETE CASCADE,
|
|
data DATE NOT NULL,
|
|
horario_inicio TEXT,
|
|
horario_fim TEXT,
|
|
status TEXT DEFAULT 'scheduled' CHECK (status IN ('scheduled', 'cancelled', 'completed', 'rescheduled')),
|
|
tipo TEXT DEFAULT 'regular' CHECK (tipo IN ('regular', 'reposicao', 'extra')),
|
|
motivo_cancelamento TEXT,
|
|
aula_original_id TEXT REFERENCES aulas(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 7. FREQUÊNCIAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS frequencias (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
turma_id TEXT NOT NULL REFERENCES turmas(id) ON DELETE CASCADE,
|
|
aula_id TEXT REFERENCES aulas(id) ON DELETE SET NULL,
|
|
data TIMESTAMPTZ NOT NULL,
|
|
foto TEXT,
|
|
verificado BOOLEAN DEFAULT FALSE,
|
|
tipo TEXT DEFAULT 'presence' CHECK (tipo IN ('presence', 'absence')),
|
|
justificativa TEXT,
|
|
justificativa_aceita BOOLEAN,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 8. DISCIPLINAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS disciplinas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
turma_id TEXT REFERENCES turmas(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 9. PERÍODOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS periodos (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 10. NOTAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS notas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
disciplina_id TEXT NOT NULL REFERENCES disciplinas(id) ON DELETE CASCADE,
|
|
valor NUMERIC(5,2) DEFAULT 0,
|
|
periodo TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(aluno_id, disciplina_id, periodo)
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 11. PAGAMENTOS / FINANCEIRO
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS pagamentos (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
contrato_id TEXT,
|
|
valor NUMERIC(10,2) NOT NULL,
|
|
desconto NUMERIC(10,2) DEFAULT 0,
|
|
tipo_desconto TEXT CHECK (tipo_desconto IN ('fixed', 'percentage')),
|
|
multa NUMERIC(10,2) DEFAULT 0,
|
|
juros NUMERIC(10,2) DEFAULT 0,
|
|
vencimento DATE NOT NULL,
|
|
status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'paid', 'overdue', 'received', 'confirmed')),
|
|
data_pagamento DATE,
|
|
tipo TEXT DEFAULT 'monthly' CHECK (tipo IN ('monthly', 'registration', 'other')),
|
|
numero_parcela INTEGER,
|
|
total_parcelas INTEGER,
|
|
descricao TEXT,
|
|
asaas_payment_id TEXT,
|
|
asaas_payment_url TEXT,
|
|
installment_id TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 12. CONTRATOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS contratos (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
titulo TEXT NOT NULL,
|
|
conteudo TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 13. MODELOS DE CONTRATO
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS modelos_contrato (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
conteudo TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Modelo padrão
|
|
INSERT INTO modelos_contrato (id, nome, conteudo)
|
|
VALUES ('default-template', 'Contrato Padrão', 'CONTRATO DE PRESTAÇÃO DE SERVIÇOS EDUCACIONAIS
|
|
|
|
Pelo presente instrumento particular, de um lado {{escola}} (CNPJ: {{cnpj_escola}}), e de outro lado o(a) aluno(a) {{aluno}}, celebram o presente contrato:
|
|
|
|
1. DO OBJETO: Prestação de serviços educacionais no curso de {{curso}}.
|
|
2. DA DURAÇÃO: O curso terá a duração estimada de {{duracao}}.
|
|
3. DO INVESTIMENTO: O CONTRATANTE pagará o valor mensal de R$ {{mensalidade}}.
|
|
4. DAS OBRIGAÇÕES: A CONTRATADA disponibilizará material e instrutores qualificados.
|
|
|
|
Data: {{data}}
|
|
|
|
___________________________________________
|
|
Assinatura do Aluno / Responsável')
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
|
-- ============================================================
|
|
-- 14. NOTIFICAÇÕES
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS notificacoes (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL,
|
|
titulo TEXT NOT NULL,
|
|
mensagem TEXT NOT NULL,
|
|
lida BOOLEAN DEFAULT FALSE,
|
|
anexo TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 15. CERTIFICADOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS certificados (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
descricao TEXT,
|
|
imagem_frente TEXT NOT NULL,
|
|
imagem_verso TEXT,
|
|
data_emissao DATE NOT NULL,
|
|
overlays_frente JSONB DEFAULT '[]',
|
|
overlays_verso JSONB DEFAULT '[]',
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 16. MODELOS DE CERTIFICADO
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS modelos_certificado (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
imagem_frente TEXT NOT NULL,
|
|
imagem_verso TEXT,
|
|
overlays_frente JSONB DEFAULT '[]',
|
|
overlays_verso JSONB DEFAULT '[]',
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 17. APOSTILAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS apostilas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
preco NUMERIC(10,2) DEFAULT 0,
|
|
descricao TEXT,
|
|
multa_percentual NUMERIC(5,2) DEFAULT 0,
|
|
juros_percentual NUMERIC(5,2) DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 18. ENTREGAS DE APOSTILAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS entregas_apostilas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
apostila_id TEXT NOT NULL REFERENCES apostilas(id) ON DELETE CASCADE,
|
|
status_entrega TEXT DEFAULT 'pending' CHECK (status_entrega IN ('pending', 'delivered')),
|
|
status_pagamento TEXT DEFAULT 'pending' CHECK (status_pagamento IN ('pending', 'paid')),
|
|
data_entrega DATE,
|
|
data_pagamento DATE,
|
|
asaas_payment_id TEXT,
|
|
asaas_payment_url TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 19. CATEGORIAS DE FUNCIONÁRIOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS categorias_funcionarios (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 20. FUNCIONÁRIOS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS funcionarios (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
nome TEXT NOT NULL,
|
|
cpf TEXT DEFAULT '',
|
|
telefone TEXT DEFAULT '',
|
|
email TEXT DEFAULT '',
|
|
data_admissao DATE,
|
|
categoria_id TEXT REFERENCES categorias_funcionarios(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 21. PROVAS / AVALIAÇÕES
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS provas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
turma_id TEXT NOT NULL REFERENCES turmas(id) ON DELETE CASCADE,
|
|
disciplina_id TEXT REFERENCES disciplinas(id) ON DELETE SET NULL,
|
|
periodo_id TEXT,
|
|
titulo TEXT NOT NULL,
|
|
duracao_minutos INTEGER DEFAULT 60,
|
|
status TEXT DEFAULT 'draft' CHECK (status IN ('draft', 'published')),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 22. QUESTÕES DAS PROVAS
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS questoes_provas (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
prova_id TEXT NOT NULL REFERENCES provas(id) ON DELETE CASCADE,
|
|
texto TEXT NOT NULL,
|
|
imagem_url TEXT,
|
|
opcoes JSONB NOT NULL DEFAULT '[]',
|
|
indice_correto INTEGER NOT NULL DEFAULT 0,
|
|
ordem INTEGER DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 23. SUBMISSÕES DE PROVAS (já existe como alunos_cobrancas no Supabase)
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS provas_submissoes (
|
|
id TEXT PRIMARY KEY DEFAULT uuid_generate_v4()::TEXT,
|
|
aluno_id TEXT NOT NULL REFERENCES alunos(id) ON DELETE CASCADE,
|
|
prova_id TEXT NOT NULL REFERENCES provas(id) ON DELETE CASCADE,
|
|
total_questoes INTEGER DEFAULT 0,
|
|
acertos INTEGER DEFAULT 0,
|
|
erros INTEGER DEFAULT 0,
|
|
percentual NUMERIC(5,2) DEFAULT 0,
|
|
nota_final NUMERIC(5,2) DEFAULT 0,
|
|
respostas JSONB DEFAULT '{}',
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(aluno_id, prova_id)
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 24. COBRANÇAS ASAAS (tabela que já existia separada)
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS alunos_cobrancas (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
aluno_id TEXT NOT NULL,
|
|
asaas_customer_id TEXT,
|
|
asaas_payment_id TEXT,
|
|
asaas_installment_id TEXT,
|
|
installment TEXT,
|
|
valor NUMERIC(10,2),
|
|
vencimento DATE,
|
|
status TEXT DEFAULT 'PENDENTE',
|
|
data_pagamento DATE,
|
|
link_boleto TEXT,
|
|
link_carne TEXT,
|
|
transaction_receipt_url TEXT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- 25. TABELA LEGADA (school_data JSON blob - ponte de migração)
|
|
-- Mantida para compatibilidade durante a transição
|
|
-- ============================================================
|
|
CREATE TABLE IF NOT EXISTS school_data (
|
|
id INTEGER PRIMARY KEY DEFAULT 1,
|
|
data JSONB NOT NULL DEFAULT '{}',
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- ÍNDICES PARA PERFORMANCE
|
|
-- ============================================================
|
|
CREATE INDEX IF NOT EXISTS idx_alunos_turma ON alunos(turma_id);
|
|
CREATE INDEX IF NOT EXISTS idx_alunos_status ON alunos(status);
|
|
CREATE INDEX IF NOT EXISTS idx_alunos_matricula ON alunos(numero_matricula);
|
|
CREATE INDEX IF NOT EXISTS idx_frequencias_aluno ON frequencias(aluno_id);
|
|
CREATE INDEX IF NOT EXISTS idx_frequencias_turma ON frequencias(turma_id);
|
|
CREATE INDEX IF NOT EXISTS idx_frequencias_data ON frequencias(data);
|
|
CREATE INDEX IF NOT EXISTS idx_notas_aluno ON notas(aluno_id);
|
|
CREATE INDEX IF NOT EXISTS idx_pagamentos_aluno ON pagamentos(aluno_id);
|
|
CREATE INDEX IF NOT EXISTS idx_pagamentos_status ON pagamentos(status);
|
|
CREATE INDEX IF NOT EXISTS idx_aulas_turma ON aulas(turma_id);
|
|
CREATE INDEX IF NOT EXISTS idx_aulas_data ON aulas(data);
|
|
CREATE INDEX IF NOT EXISTS idx_notificacoes_aluno ON notificacoes(aluno_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cobrancas_aluno ON alunos_cobrancas(aluno_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cobrancas_asaas ON alunos_cobrancas(asaas_payment_id);
|
|
CREATE INDEX IF NOT EXISTS idx_cobrancas_installment ON alunos_cobrancas(asaas_installment_id);
|