feat: garantir que o banco seja ajustado a cada deploy

This commit is contained in:
NANDO9322 2025-12-09 18:02:28 -03:00
parent 566bb540e4
commit 323261fa23
3 changed files with 70 additions and 44 deletions

View file

@ -50,6 +50,9 @@ func main() {
queries, pool := db.Connect(cfg)
defer pool.Close()
// Run Migrations
db.Migrate(pool)
// Initialize services
profissionaisService := profissionais.NewService(queries)
authService := auth.NewService(queries, profissionaisService, cfg)

View file

@ -1,41 +1,58 @@
package db
import (
"context"
"log"
"context"
"embed"
"log"
"photum-backend/internal/config"
"photum-backend/internal/db/generated"
"photum-backend/internal/config"
"photum-backend/internal/db/generated"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/jackc/pgx/v5/pgxpool"
)
//go:embed schema.sql
var schemaFS embed.FS
func Connect(cfg *config.Config) (*generated.Queries, *pgxpool.Pool) {
log.Printf("Connecting to database with DSN: %#v", cfg.DBDsn)
poolConfig, err := pgxpool.ParseConfig(cfg.DBDsn)
if err != nil {
log.Fatalf("Unable to parse DB DSN: %v", err)
}
log.Printf("Connecting to database with DSN: %#v", cfg.DBDsn)
poolConfig, err := pgxpool.ParseConfig(cfg.DBDsn)
if err != nil {
log.Fatalf("Unable to parse DB DSN: %v", err)
}
// Diagnostic log (password presence only)
if poolConfig != nil && poolConfig.ConnConfig != nil {
hasPassword := poolConfig.ConnConfig.Password != ""
log.Printf("DB config user=%s host=%s port=%d password_set=%t",
poolConfig.ConnConfig.User,
poolConfig.ConnConfig.Host,
poolConfig.ConnConfig.Port,
hasPassword,
)
}
// Diagnostic log (password presence only)
if poolConfig != nil && poolConfig.ConnConfig != nil {
hasPassword := poolConfig.ConnConfig.Password != ""
log.Printf("DB config user=%s host=%s port=%d password_set=%t",
poolConfig.ConnConfig.User,
poolConfig.ConnConfig.Host,
poolConfig.ConnConfig.Port,
hasPassword,
)
}
pool, err := pgxpool.NewWithConfig(context.Background(), poolConfig)
if err != nil {
log.Fatalf("Unable to connect to database: %v", err)
}
pool, err := pgxpool.NewWithConfig(context.Background(), poolConfig)
if err != nil {
log.Fatalf("Unable to connect to database: %v", err)
}
if err := pool.Ping(context.Background()); err != nil {
log.Fatalf("Database ping failed: %v", err)
}
if err := pool.Ping(context.Background()); err != nil {
log.Fatalf("Database ping failed: %v", err)
}
return generated.New(pool), pool
return generated.New(pool), pool
}
func Migrate(pool *pgxpool.Pool) {
log.Println("Applying database migration...")
schema, err := schemaFS.ReadFile("schema.sql")
if err != nil {
log.Fatalf("Failed to read schema file: %v", err)
}
if _, err := pool.Exec(context.Background(), string(schema)); err != nil {
log.Fatalf("Failed to execute migration: %v", err)
}
log.Println("Database migration applied successfully.")
}

View file

@ -1,6 +1,6 @@
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE usuarios (
CREATE TABLE IF NOT EXISTS usuarios (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) UNIQUE NOT NULL,
senha_hash VARCHAR(255) NOT NULL,
@ -10,7 +10,7 @@ CREATE TABLE usuarios (
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE funcoes_profissionais (
CREATE TABLE IF NOT EXISTS funcoes_profissionais (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(50) UNIQUE NOT NULL,
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(),
@ -22,9 +22,10 @@ INSERT INTO funcoes_profissionais (nome) VALUES
('Cinegrafista'),
('Recepcionista'),
('Fixo Photum'),
('Controle');
('Controle')
ON CONFLICT (nome) DO NOTHING;
CREATE TABLE cadastro_profissionais (
CREATE TABLE IF NOT EXISTS cadastro_profissionais (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
usuario_id UUID REFERENCES usuarios(id) ON DELETE SET NULL,
nome VARCHAR(255) NOT NULL,
@ -54,7 +55,7 @@ CREATE TABLE cadastro_profissionais (
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE refresh_tokens (
CREATE TABLE IF NOT EXISTS refresh_tokens (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
usuario_id UUID NOT NULL REFERENCES usuarios(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL,
@ -66,7 +67,7 @@ CREATE TABLE refresh_tokens (
);
-- Cursos Table
CREATE TABLE cursos (
CREATE TABLE IF NOT EXISTS cursos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(100) UNIQUE NOT NULL,
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
@ -79,10 +80,11 @@ INSERT INTO cursos (nome) VALUES
('Farmácia'), ('Fisioterapia'), ('Gastronomia'), ('Historia'), ('Jornalismo'), ('Med. Veterinária'), ('Medicina'),
('Nutrição'), ('Odontologia'), ('Outro'), ('Pedagogia'), ('Publicidade'), ('Superior Diversos'), ('Tec. Diversos'),
('Termomecânica'), ('Unificados'), ('Tec. Enfermagem'), ('Quimica'), ('EFI / EF II / EM'), ('Psicologia'),
('Terapia Ocupacinal'), ('R.I');
('Terapia Ocupacinal'), ('R.I')
ON CONFLICT (nome) DO NOTHING;
-- Empresas Table
CREATE TABLE empresas (
CREATE TABLE IF NOT EXISTS empresas (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(100) UNIQUE NOT NULL,
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
@ -92,10 +94,11 @@ INSERT INTO empresas (nome) VALUES
('Arte Formaturas'), ('JR Formaturas'), ('Perfil'), ('Photum'), ('Populi Formaturas'), ('Prime'), ('Smart'), ('Viva SP'),
('Antares'), ('Forcamp'), ('PNI'), ('Fábio Ribeiro'), ('Told - B2_(CAMPINAS)'), ('Told - B2_(RECIFE)'),
('NOVO - Told - B2_(SP)'), ('NOVO - Told - RUB_(SP)'), ('NOVO - TOLD'), ('Alpha Digital'), ('Golden'), ('Festa da Beca'),
('Ponta Eventos'), ('Toy SP'), ('MVP Formaturas'), ('RUB');
('Ponta Eventos'), ('Toy SP'), ('MVP Formaturas'), ('RUB')
ON CONFLICT (nome) DO NOTHING;
-- Anos Formaturas Table
CREATE TABLE anos_formaturas (
CREATE TABLE IF NOT EXISTS anos_formaturas (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
ano_semestre VARCHAR(20) UNIQUE NOT NULL, -- Ex: 2019.2
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
@ -104,10 +107,11 @@ CREATE TABLE anos_formaturas (
INSERT INTO anos_formaturas (ano_semestre) VALUES
('2019.2'), ('2020.1'), ('2020.2'), ('2021.1'), ('2021.2'), ('2022.1'), ('2022.2'), ('2023.1'), ('2023.2'),
('2024.1'), ('2024.2'), ('2025.1'), ('2025.2'), ('2026.1'), ('2026.2'), ('2027.1'), ('2027.2'), ('2028.1'),
('2028.2'), ('2029.1'), ('2029.2');
('2028.2'), ('2029.1'), ('2029.2')
ON CONFLICT (ano_semestre) DO NOTHING;
-- Tipos Servicos Table
CREATE TABLE tipos_servicos (
CREATE TABLE IF NOT EXISTS tipos_servicos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(50) UNIQUE NOT NULL,
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
@ -115,10 +119,11 @@ CREATE TABLE tipos_servicos (
INSERT INTO tipos_servicos (nome) VALUES
('Fotógrafo'), ('Recepcionista'), ('Cinegrafista'), ('Coordenação'), ('Ponto de Foto'), ('Ponto de ID'), ('Estúdio'),
('Outro'), ('Controle');
('Outro'), ('Controle')
ON CONFLICT (nome) DO NOTHING;
-- Tipos Eventos Table
CREATE TABLE tipos_eventos (
CREATE TABLE IF NOT EXISTS tipos_eventos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
nome VARCHAR(100) UNIQUE NOT NULL,
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
@ -127,10 +132,11 @@ CREATE TABLE tipos_eventos (
INSERT INTO tipos_eventos (nome) VALUES
('Identificação'), ('Baile'), ('Colação'), ('Col/Baile (mesmo local)'), ('Col/Baile (local diferente)'), ('Missa / Culto'),
('Churrasco'), ('Trote'), ('Outro'), ('Balada'), ('Jantar'), ('Festa Junina'), ('Colação Oficial'), ('Family Day'),
('Refeição'), ('Estudio ID e Family Day'), ('Estudio Colação / Baile');
('Refeição'), ('Estudio ID e Family Day'), ('Estudio Colação / Baile')
ON CONFLICT (nome) DO NOTHING;
-- Precos Tipos Eventos Table (Junction Table for Pricing)
CREATE TABLE precos_tipos_eventos (
CREATE TABLE IF NOT EXISTS precos_tipos_eventos (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tipo_evento_id UUID REFERENCES tipos_eventos(id) ON DELETE CASCADE,
funcao_profissional_id UUID REFERENCES funcoes_profissionais(id) ON DELETE CASCADE,