ultisuite-backend/migrations/000040_hosted_mail_migration.up.sql
R3D347HR4Y 7143a36c19
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
feat(mail): integrate Stalwart hosted mail and migration features
- Added configuration options for Stalwart hosted mail in .env.example.
- Updated Docker Compose to include Stalwart service with health checks.
- Introduced new API endpoints for managing mail domains and migration projects.
- Enhanced Authentik blueprints for user enrollment and post-migration security.
- Updated OAuth handling for Google and Microsoft migration processes.
- Improved error handling and response structures in the mail API.
- Added integration tests for email claiming and migration workflows.
2026-06-13 12:47:08 +02:00

97 lines
3.7 KiB
SQL

-- Hosted mail domains and mailboxes (Stalwart provisioning)
CREATE TABLE mail_domains (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name TEXT NOT NULL UNIQUE,
status TEXT NOT NULL DEFAULT 'pending_verification',
verification_token TEXT NOT NULL DEFAULT '',
dkim_selector TEXT NOT NULL DEFAULT '',
dkim_public_key TEXT NOT NULL DEFAULT '',
stalwart_domain_id TEXT NOT NULL DEFAULT '',
is_platform_domain BOOLEAN NOT NULL DEFAULT false,
mx_verified_at TIMESTAMPTZ,
txt_verified_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_mail_domains_status ON mail_domains(status);
CREATE TABLE mailboxes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
domain_id UUID NOT NULL REFERENCES mail_domains(id) ON DELETE CASCADE,
local_part TEXT NOT NULL,
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
mail_account_id UUID REFERENCES mail_accounts(id) ON DELETE SET NULL,
stalwart_account_id TEXT NOT NULL DEFAULT '',
quota_bytes BIGINT NOT NULL DEFAULT 5368709120,
status TEXT NOT NULL DEFAULT 'active',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(domain_id, local_part)
);
CREATE INDEX idx_mailboxes_user ON mailboxes(user_id);
CREATE INDEX idx_mailboxes_mail_account ON mailboxes(mail_account_id);
-- Migration projects (Google Workspace / Microsoft 365 transitions)
CREATE TABLE migration_projects (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
domain_id UUID REFERENCES mail_domains(id) ON DELETE SET NULL,
name TEXT NOT NULL DEFAULT '',
source_provider TEXT NOT NULL DEFAULT 'google',
status TEXT NOT NULL DEFAULT 'draft',
cutover_at TIMESTAMPTZ,
delta_mode BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_migration_projects_status ON migration_projects(status);
CREATE TABLE migration_invites (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
project_id UUID NOT NULL REFERENCES migration_projects(id) ON DELETE CASCADE,
email TEXT NOT NULL,
token TEXT NOT NULL UNIQUE,
status TEXT NOT NULL DEFAULT 'invited',
claimed_at TIMESTAMPTZ,
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(project_id, email)
);
CREATE INDEX idx_migration_invites_token ON migration_invites(token);
CREATE INDEX idx_migration_invites_email ON migration_invites(email);
CREATE TABLE migration_jobs (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
project_id UUID NOT NULL REFERENCES migration_projects(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
service TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
cursor_json JSONB NOT NULL DEFAULT '{}',
stats_json JSONB NOT NULL DEFAULT '{}',
error TEXT NOT NULL DEFAULT '',
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(project_id, user_id, service)
);
CREATE INDEX idx_migration_jobs_status ON migration_jobs(status);
CREATE TABLE migration_credentials (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
project_id UUID NOT NULL REFERENCES migration_projects(id) ON DELETE CASCADE,
provider TEXT NOT NULL,
encrypted_token BYTEA NOT NULL,
scopes TEXT[] NOT NULL DEFAULT '{}',
expires_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(user_id, project_id, provider)
);
CREATE INDEX idx_migration_credentials_user ON migration_credentials(user_id);