[split-required] [guardrail-change] Enforce 500 LOC budget across all services
Install LOC guardrails (check-loc.sh, architecture.md, pre-commit hook) and split all 44 files exceeding 500 LOC into domain-focused modules: - consent-service (Go): models, handlers, services, database splits - backend-core (Python): security_api, rbac_api, pdf_service, auth splits - admin-core (TypeScript): 5 page.tsx + sidebar extractions - pitch-deck (TypeScript): 6 slides, 3 UI components, engine.ts splits - voice-service (Python): enhanced_task_orchestrator split Result: 0 violations, 36 exempted (pipeline, tests, pure-data files). Go build verified clean. No behavior changes — pure structural splits. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
114
consent-service/internal/database/migrate_email.go
Normal file
114
consent-service/internal/database/migrate_email.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// migrateEmail creates email template tables, settings, and indexes (Phase 8).
|
||||
func migrateEmail(db *DB) error {
|
||||
ctx := context.Background()
|
||||
|
||||
migrations := []string{
|
||||
// =============================================
|
||||
// Phase 8: E-Mail Templates (Transactional)
|
||||
// =============================================
|
||||
|
||||
// Email templates (like legal_documents)
|
||||
`CREATE TABLE IF NOT EXISTS email_templates (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
type VARCHAR(50) UNIQUE NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
sort_order INT DEFAULT 0,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
)`,
|
||||
|
||||
// Email template versions (like document_versions)
|
||||
`CREATE TABLE IF NOT EXISTS email_template_versions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
template_id UUID REFERENCES email_templates(id) ON DELETE CASCADE,
|
||||
version VARCHAR(20) NOT NULL,
|
||||
language VARCHAR(5) DEFAULT 'de',
|
||||
subject VARCHAR(500) NOT NULL,
|
||||
body_html TEXT NOT NULL,
|
||||
body_text TEXT NOT NULL,
|
||||
summary TEXT,
|
||||
status VARCHAR(20) DEFAULT 'draft',
|
||||
published_at TIMESTAMPTZ,
|
||||
scheduled_publish_at TIMESTAMPTZ,
|
||||
created_by UUID REFERENCES users(id),
|
||||
approved_by UUID REFERENCES users(id),
|
||||
approved_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
UNIQUE(template_id, version, language)
|
||||
)`,
|
||||
|
||||
// Email template approvals (like version_approvals)
|
||||
`CREATE TABLE IF NOT EXISTS email_template_approvals (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
version_id UUID REFERENCES email_template_versions(id) ON DELETE CASCADE,
|
||||
approver_id UUID REFERENCES users(id),
|
||||
action VARCHAR(30) NOT NULL,
|
||||
comment TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
)`,
|
||||
|
||||
// Email send logs for audit
|
||||
`CREATE TABLE IF NOT EXISTS email_send_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
version_id UUID REFERENCES email_template_versions(id) ON DELETE SET NULL,
|
||||
recipient VARCHAR(255) NOT NULL,
|
||||
subject VARCHAR(500) NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'queued',
|
||||
error_msg TEXT,
|
||||
variables JSONB,
|
||||
sent_at TIMESTAMPTZ,
|
||||
delivered_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
)`,
|
||||
|
||||
// Global email settings (logo, colors, signature)
|
||||
`CREATE TABLE IF NOT EXISTS email_template_settings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
logo_url TEXT,
|
||||
logo_base64 TEXT,
|
||||
company_name VARCHAR(255) DEFAULT 'BreakPilot',
|
||||
sender_name VARCHAR(255) DEFAULT 'BreakPilot',
|
||||
sender_email VARCHAR(255) DEFAULT 'noreply@breakpilot.app',
|
||||
reply_to_email VARCHAR(255),
|
||||
footer_html TEXT,
|
||||
footer_text TEXT,
|
||||
primary_color VARCHAR(7) DEFAULT '#2563eb',
|
||||
secondary_color VARCHAR(7) DEFAULT '#64748b',
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_by UUID REFERENCES users(id)
|
||||
)`,
|
||||
|
||||
// Insert default email settings
|
||||
`INSERT INTO email_template_settings (id, company_name, sender_name, sender_email, primary_color, secondary_color)
|
||||
VALUES (gen_random_uuid(), 'BreakPilot', 'BreakPilot', 'noreply@breakpilot.app', '#2563eb', '#64748b')
|
||||
ON CONFLICT DO NOTHING`,
|
||||
|
||||
// Phase 8 Indexes
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_templates_type ON email_templates(type)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_template_versions_template ON email_template_versions(template_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_template_versions_status ON email_template_versions(status)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_template_approvals_version ON email_template_approvals(version_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_send_logs_user ON email_send_logs(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_send_logs_created ON email_send_logs(created_at)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_send_logs_status ON email_send_logs(status)`,
|
||||
}
|
||||
|
||||
for _, migration := range migrations {
|
||||
if _, err := db.Pool.Exec(ctx, migration); err != nil {
|
||||
return fmt.Errorf("migrateEmail: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user