gohorsejobs/backend/migrations/027_create_email_system.sql
Tiago Yamamoto 841b1d780c feat: Email System, Avatar Upload, Email Templates UI, and Public Job Posting
- Backend: Email producer (LavinMQ), EmailService interface
- Backend: CRUD API for email_templates and email_settings
- Backend: avatar_url field in users table + UpdateMyProfile support
- Backend: StorageService for pre-signed URLs
- NestJS: Email consumer with Nodemailer and Handlebars
- Frontend: Email Templates admin pages (list/edit)
- Frontend: Updated profileApi.uploadAvatar with pre-signed URL flow
- Frontend: New /post-job public page (company registration + job creation wizard)
- Migrations: 027_create_email_system.sql, 028_add_avatar_url_to_users.sql
2025-12-26 12:21:34 -03:00

53 lines
2.8 KiB
SQL

-- Migration: Create Email System Tables (Settings, Templates)
-- Description: Stores configuration for Email Service (SMTP, LavinMQ) and Templates.
-- 1. Email Settings (Singleton or Key-Value)
-- We can reuse `system_settings` or `external_services_credentials` for the actual secrets.
-- But requirements said "Criar tabela email_settings". Let's create it for specific non-secret config or reference.
-- Actually, the user asked for `email_settings` to store SMTP (Host, Port, User, Pass) and LavinMQ.
-- Since we have `external_services_credentials` for encrypted data, we should probably stick to that for passwords.
-- However, for the sake of the requirement "Criar tabela email_settings", let's create it but maybe keep passwords encrypted or reference them.
-- User Requirement: "Armazenar SMTP (Host, Port, User, Pass) e as credenciais do LavinMQ."
-- We will create a table that holds this. For security, we should encrypt 'pass' fields, but for this exercise we might store them plaintext or assume app handles encryption.
-- Given `external_services_credentials` exists, we can use it. But the user explicitly asked for `email_settings`.
-- Let's make `email_settings` a single row table or key-value.
-- Let's use a structured table for simplicity as requested.
CREATE TABLE IF NOT EXISTS email_settings (
id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
provider VARCHAR(50) NOT NULL DEFAULT 'smtp', -- smtp, ses, sendgrid
-- SMTP Config
smtp_host VARCHAR(255),
smtp_port INTEGER,
smtp_user VARCHAR(255),
smtp_pass VARCHAR(255), -- Ideally encrypted, but we'll store as is or encrypted string
smtp_secure BOOLEAN DEFAULT true,
sender_name VARCHAR(255) DEFAULT 'GoHorse Jobs',
sender_email VARCHAR(255) DEFAULT 'no-reply@gohorsejobs.com',
-- LavinMQ Config
amqp_url VARCHAR(255), -- amqp://user:pass@host:port/vhost
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT true
);
-- 2. Email Templates
CREATE TABLE IF NOT EXISTS email_templates (
id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
slug VARCHAR(100) UNIQUE NOT NULL, -- e.g. 'welcome-user', 'reset-password'
subject VARCHAR(255) NOT NULL,
body_html TEXT NOT NULL,
variables JSONB DEFAULT '[]', -- List of expected variables e.g. ["name", "link"]
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Seed some initial templates
INSERT INTO email_templates (slug, subject, body_html, variables)
VALUES
('welcome-candidate', 'Welcome to GoHorse Jobs!', '<h1>Hello {{name}},</h1><p>Welcome to GoHorse Jobs. We are excited to have you.</p>', '["name"]'),
('reset-password', 'Reset your password', '<p>Click <a href="{{link}}">here</a> to reset your password.</p>', '["link"]')
ON CONFLICT (slug) DO NOTHING;