Files
Sankofa/api/src/db/migrations/019_deployments.ts
defiQUG 9daf1fd378 Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution
- Enhance API schema with expanded type definitions and resolvers
- Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth
- Implement new services: AI optimization, billing, blockchain, compliance, marketplace
- Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage)
- Update Crossplane provider with enhanced VM management capabilities
- Add comprehensive test suite for API endpoints and services
- Update frontend components with improved GraphQL subscriptions and real-time updates
- Enhance security configurations and headers (CSP, CORS, etc.)
- Update documentation and configuration files
- Add new CI/CD workflows and validation scripts
- Implement design system improvements and UI enhancements
2025-12-12 18:01:35 -08:00

153 lines
5.0 KiB
TypeScript

import { Migration } from '../migrate.js'
export const up: Migration['up'] = async (db) => {
// Deployments table
await db.query(`
CREATE TABLE IF NOT EXISTS deployments (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
product_id UUID REFERENCES products(id) ON DELETE SET NULL,
product_version_id UUID REFERENCES product_versions(id) ON DELETE SET NULL,
template_id UUID REFERENCES templates(id) ON DELETE SET NULL,
template_version_id UUID REFERENCES template_versions(id) ON DELETE SET NULL,
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
region VARCHAR(100),
status VARCHAR(50) NOT NULL DEFAULT 'PENDING' CHECK (status IN (
'PENDING',
'PROVISIONING',
'DEPLOYING',
'RUNNING',
'UPDATING',
'STOPPED',
'FAILED',
'DELETING',
'DELETED'
)),
deployment_type VARCHAR(50) NOT NULL CHECK (deployment_type IN (
'TERRAFORM',
'HELM',
'ANSIBLE',
'KUBERNETES',
'HYBRID'
)),
parameters JSONB DEFAULT '{}'::jsonb,
rendered_content TEXT,
terraform_state JSONB,
outputs JSONB DEFAULT '{}'::jsonb,
error_message TEXT,
created_by UUID REFERENCES users(id) ON DELETE SET NULL,
started_at TIMESTAMP WITH TIME ZONE,
completed_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
)
`)
// Deployment logs table
await db.query(`
CREATE TABLE IF NOT EXISTS deployment_logs (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
deployment_id UUID NOT NULL REFERENCES deployments(id) ON DELETE CASCADE,
level VARCHAR(20) NOT NULL CHECK (level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),
message TEXT NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
)
`)
// Deployment resources table (links deployments to resources)
await db.query(`
CREATE TABLE IF NOT EXISTS deployment_resources (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
deployment_id UUID NOT NULL REFERENCES deployments(id) ON DELETE CASCADE,
resource_id UUID REFERENCES resources(id) ON DELETE SET NULL,
resource_type VARCHAR(100) NOT NULL,
resource_name VARCHAR(255) NOT NULL,
provider_resource_id VARCHAR(255),
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
)
`)
// Deployment events table (for event sourcing)
await db.query(`
CREATE TABLE IF NOT EXISTS deployment_events (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
deployment_id UUID NOT NULL REFERENCES deployments(id) ON DELETE CASCADE,
event_type VARCHAR(100) NOT NULL,
event_data JSONB DEFAULT '{}'::jsonb,
created_by UUID REFERENCES users(id) ON DELETE SET NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
)
`)
// Indexes
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployments_tenant ON deployments(tenant_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployments_status ON deployments(status)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployments_product ON deployments(product_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployments_template ON deployments(template_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployments_region ON deployments(region)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployment_logs_deployment ON deployment_logs(deployment_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployment_logs_created ON deployment_logs(deployment_id, created_at)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployment_resources_deployment ON deployment_resources(deployment_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployment_resources_resource ON deployment_resources(resource_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployment_events_deployment ON deployment_events(deployment_id)
`)
await db.query(`
CREATE INDEX IF NOT EXISTS idx_deployment_events_type ON deployment_events(deployment_id, event_type)
`)
// Update triggers
await db.query(`
CREATE TRIGGER update_deployments_updated_at
BEFORE UPDATE ON deployments
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column()
`)
await db.query(`
CREATE TRIGGER update_deployment_resources_updated_at
BEFORE UPDATE ON deployment_resources
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column()
`)
}
export const down: Migration['down'] = async (db) => {
await db.query(`DROP TABLE IF EXISTS deployment_events`)
await db.query(`DROP TABLE IF EXISTS deployment_resources`)
await db.query(`DROP TABLE IF EXISTS deployment_logs`)
await db.query(`DROP TABLE IF EXISTS deployments`)
}