473 lines
17 KiB
PL/PgSQL
473 lines
17 KiB
PL/PgSQL
-- ================================================================
|
|
-- PMC Database Schema - Initial Setup
|
|
-- Version: 1.0.0
|
|
-- Date: 2025-12-08
|
|
-- ================================================================
|
|
|
|
-- Extensions
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
|
|
|
-- ================================================================
|
|
-- SCHEMAS
|
|
-- ================================================================
|
|
|
|
-- Auth schema: usuarios, tenants, sesiones
|
|
CREATE SCHEMA IF NOT EXISTS auth;
|
|
|
|
-- CRM schema: clientes, marcas, productos
|
|
CREATE SCHEMA IF NOT EXISTS crm;
|
|
|
|
-- Projects schema: proyectos, campanas, briefs
|
|
CREATE SCHEMA IF NOT EXISTS projects;
|
|
|
|
-- Generation schema: jobs, workflows, modelos
|
|
CREATE SCHEMA IF NOT EXISTS generation;
|
|
|
|
-- Assets schema: biblioteca de archivos
|
|
CREATE SCHEMA IF NOT EXISTS assets;
|
|
|
|
-- ================================================================
|
|
-- AUTH SCHEMA
|
|
-- ================================================================
|
|
|
|
-- Planes de tenant
|
|
CREATE TABLE auth.tenant_plans (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name VARCHAR(100) NOT NULL UNIQUE,
|
|
code VARCHAR(50) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
price_monthly DECIMAL(10,2) DEFAULT 0,
|
|
price_yearly DECIMAL(10,2) DEFAULT 0,
|
|
max_users INT DEFAULT 5,
|
|
max_clients INT DEFAULT 10,
|
|
max_brands INT DEFAULT 20,
|
|
max_generations_month INT DEFAULT 100,
|
|
max_storage_bytes BIGINT DEFAULT 5368709120, -- 5GB
|
|
max_custom_models INT DEFAULT 0,
|
|
max_training_month INT DEFAULT 0,
|
|
features JSONB,
|
|
is_active BOOLEAN DEFAULT true,
|
|
sort_order INT DEFAULT 0,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Tenants (organizaciones)
|
|
CREATE TABLE auth.tenants (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL UNIQUE,
|
|
plan_id UUID NOT NULL REFERENCES auth.tenant_plans(id),
|
|
status VARCHAR(20) DEFAULT 'trial' CHECK (status IN ('trial', 'active', 'suspended', 'cancelled')),
|
|
logo_url VARCHAR(500),
|
|
settings JSONB,
|
|
trial_ends_at DATE,
|
|
billing_cycle_start DATE,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX idx_tenants_slug ON auth.tenants(slug);
|
|
CREATE INDEX idx_tenants_status ON auth.tenants(status);
|
|
|
|
-- Usuarios
|
|
CREATE TABLE auth.users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
email VARCHAR(255) NOT NULL,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
first_name VARCHAR(100),
|
|
last_name VARCHAR(100),
|
|
avatar_url VARCHAR(500),
|
|
role VARCHAR(20) DEFAULT 'viewer' CHECK (role IN ('owner', 'admin', 'creative', 'analyst', 'viewer', 'client_portal')),
|
|
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'active', 'suspended')),
|
|
last_login_at TIMESTAMPTZ,
|
|
preferences JSONB,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, email)
|
|
);
|
|
|
|
CREATE INDEX idx_users_tenant ON auth.users(tenant_id);
|
|
CREATE INDEX idx_users_email ON auth.users(email);
|
|
CREATE INDEX idx_users_status ON auth.users(status);
|
|
|
|
-- Sesiones
|
|
CREATE TABLE auth.sessions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
refresh_token_hash VARCHAR(500) NOT NULL,
|
|
device_info VARCHAR(100),
|
|
ip_address VARCHAR(50),
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
last_used_at TIMESTAMPTZ,
|
|
is_active BOOLEAN DEFAULT true
|
|
);
|
|
|
|
CREATE INDEX idx_sessions_user ON auth.sessions(user_id);
|
|
CREATE INDEX idx_sessions_expires ON auth.sessions(expires_at);
|
|
|
|
-- Invitaciones
|
|
CREATE TABLE auth.invitations (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
email VARCHAR(255) NOT NULL,
|
|
role VARCHAR(20) NOT NULL,
|
|
token VARCHAR(100) NOT NULL UNIQUE,
|
|
invited_by UUID REFERENCES auth.users(id),
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
accepted_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_invitations_token ON auth.invitations(token);
|
|
CREATE INDEX idx_invitations_tenant ON auth.invitations(tenant_id);
|
|
|
|
-- ================================================================
|
|
-- CRM SCHEMA
|
|
-- ================================================================
|
|
|
|
-- Clientes
|
|
CREATE TABLE crm.clients (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL,
|
|
type VARCHAR(20) DEFAULT 'company' CHECK (type IN ('company', 'individual')),
|
|
industry VARCHAR(100),
|
|
website VARCHAR(500),
|
|
logo_url VARCHAR(500),
|
|
contact_name VARCHAR(200),
|
|
contact_email VARCHAR(255),
|
|
contact_phone VARCHAR(50),
|
|
notes TEXT,
|
|
is_active BOOLEAN DEFAULT true,
|
|
metadata JSONB,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_clients_tenant ON crm.clients(tenant_id);
|
|
CREATE INDEX idx_clients_slug ON crm.clients(tenant_id, slug);
|
|
|
|
-- Marcas
|
|
CREATE TABLE crm.brands (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
client_id UUID NOT NULL REFERENCES crm.clients(id) ON DELETE CASCADE,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
logo_url VARCHAR(500),
|
|
primary_color VARCHAR(7),
|
|
secondary_color VARCHAR(7),
|
|
brand_voice TEXT,
|
|
target_audience TEXT,
|
|
guidelines_url VARCHAR(500),
|
|
is_active BOOLEAN DEFAULT true,
|
|
metadata JSONB,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_brands_tenant ON crm.brands(tenant_id);
|
|
CREATE INDEX idx_brands_client ON crm.brands(client_id);
|
|
|
|
-- Productos
|
|
CREATE TABLE crm.products (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
brand_id UUID NOT NULL REFERENCES crm.brands(id) ON DELETE CASCADE,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
sku VARCHAR(100),
|
|
category VARCHAR(100),
|
|
price DECIMAL(10,2),
|
|
currency VARCHAR(3) DEFAULT 'USD',
|
|
image_urls JSONB, -- Array of image URLs
|
|
attributes JSONB, -- Custom attributes
|
|
is_active BOOLEAN DEFAULT true,
|
|
metadata JSONB,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_products_tenant ON crm.products(tenant_id);
|
|
CREATE INDEX idx_products_brand ON crm.products(brand_id);
|
|
|
|
-- ================================================================
|
|
-- PROJECTS SCHEMA
|
|
-- ================================================================
|
|
|
|
-- Proyectos
|
|
CREATE TABLE projects.projects (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
client_id UUID REFERENCES crm.clients(id) ON DELETE SET NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
status VARCHAR(20) DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'paused', 'completed', 'archived')),
|
|
start_date DATE,
|
|
end_date DATE,
|
|
budget DECIMAL(12,2),
|
|
currency VARCHAR(3) DEFAULT 'USD',
|
|
metadata JSONB,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_projects_tenant ON projects.projects(tenant_id);
|
|
CREATE INDEX idx_projects_client ON projects.projects(client_id);
|
|
CREATE INDEX idx_projects_status ON projects.projects(status);
|
|
|
|
-- Campanas
|
|
CREATE TABLE projects.campaigns (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
project_id UUID NOT NULL REFERENCES projects.projects(id) ON DELETE CASCADE,
|
|
brand_id UUID REFERENCES crm.brands(id) ON DELETE SET NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
objective TEXT,
|
|
target_audience TEXT,
|
|
channels JSONB, -- Array of channels: instagram, facebook, etc
|
|
status VARCHAR(20) DEFAULT 'draft' CHECK (status IN ('draft', 'planning', 'in_progress', 'review', 'approved', 'published')),
|
|
start_date DATE,
|
|
end_date DATE,
|
|
brief JSONB, -- Campaign brief details
|
|
metadata JSONB,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_campaigns_tenant ON projects.campaigns(tenant_id);
|
|
CREATE INDEX idx_campaigns_project ON projects.campaigns(project_id);
|
|
CREATE INDEX idx_campaigns_brand ON projects.campaigns(brand_id);
|
|
|
|
-- ================================================================
|
|
-- GENERATION SCHEMA
|
|
-- ================================================================
|
|
|
|
-- Workflows de generacion
|
|
CREATE TABLE generation.workflows (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name VARCHAR(255) NOT NULL,
|
|
code VARCHAR(100) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
type VARCHAR(50) NOT NULL, -- image, text, composite
|
|
input_schema JSONB NOT NULL, -- JSON Schema for inputs
|
|
output_schema JSONB, -- Expected outputs
|
|
comfyui_template JSONB, -- ComfyUI workflow JSON
|
|
estimated_time_seconds INT DEFAULT 60,
|
|
is_active BOOLEAN DEFAULT true,
|
|
is_system BOOLEAN DEFAULT true, -- System vs custom workflow
|
|
tenant_id UUID REFERENCES auth.tenants(id) ON DELETE CASCADE, -- NULL for system workflows
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_workflows_code ON generation.workflows(code);
|
|
CREATE INDEX idx_workflows_tenant ON generation.workflows(tenant_id);
|
|
|
|
-- Jobs de generacion
|
|
CREATE TABLE generation.jobs (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES auth.users(id),
|
|
workflow_id UUID NOT NULL REFERENCES generation.workflows(id),
|
|
campaign_id UUID REFERENCES projects.campaigns(id) ON DELETE SET NULL,
|
|
brand_id UUID REFERENCES crm.brands(id) ON DELETE SET NULL,
|
|
status VARCHAR(20) DEFAULT 'queued' CHECK (status IN ('queued', 'processing', 'completed', 'failed', 'cancelled')),
|
|
priority INT DEFAULT 0,
|
|
input_params JSONB NOT NULL,
|
|
output_data JSONB, -- Results after completion
|
|
error_message TEXT,
|
|
progress INT DEFAULT 0, -- 0-100
|
|
started_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
processing_time_ms INT,
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_jobs_tenant ON generation.jobs(tenant_id);
|
|
CREATE INDEX idx_jobs_user ON generation.jobs(user_id);
|
|
CREATE INDEX idx_jobs_status ON generation.jobs(status);
|
|
CREATE INDEX idx_jobs_created ON generation.jobs(created_at DESC);
|
|
|
|
-- Modelos personalizados (LoRAs)
|
|
CREATE TABLE generation.custom_models (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
brand_id UUID REFERENCES crm.brands(id) ON DELETE SET NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
type VARCHAR(50) NOT NULL, -- lora, checkpoint, embedding
|
|
file_path VARCHAR(500) NOT NULL,
|
|
file_size_bytes BIGINT,
|
|
trigger_word VARCHAR(100),
|
|
training_images_count INT,
|
|
preview_images JSONB, -- Array of preview image URLs
|
|
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'training', 'ready', 'failed')),
|
|
training_config JSONB,
|
|
metadata JSONB,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX idx_custom_models_tenant ON generation.custom_models(tenant_id);
|
|
CREATE INDEX idx_custom_models_brand ON generation.custom_models(brand_id);
|
|
|
|
-- ================================================================
|
|
-- ASSETS SCHEMA
|
|
-- ================================================================
|
|
|
|
-- Colecciones
|
|
CREATE TABLE assets.collections (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
is_public BOOLEAN DEFAULT false,
|
|
parent_id UUID REFERENCES assets.collections(id) ON DELETE SET NULL,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_collections_tenant ON assets.collections(tenant_id);
|
|
CREATE INDEX idx_collections_parent ON assets.collections(parent_id);
|
|
|
|
-- Assets (archivos)
|
|
CREATE TABLE assets.assets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
|
|
collection_id UUID REFERENCES assets.collections(id) ON DELETE SET NULL,
|
|
job_id UUID REFERENCES generation.jobs(id) ON DELETE SET NULL, -- Si fue generado
|
|
name VARCHAR(255) NOT NULL,
|
|
original_filename VARCHAR(255),
|
|
mime_type VARCHAR(100) NOT NULL,
|
|
file_path VARCHAR(500) NOT NULL,
|
|
file_size_bytes BIGINT NOT NULL,
|
|
width INT,
|
|
height INT,
|
|
duration_seconds DECIMAL(10,2), -- For video/audio
|
|
thumbnail_url VARCHAR(500),
|
|
metadata JSONB, -- EXIF, AI generation params, etc
|
|
tags JSONB, -- Array of tags
|
|
is_public BOOLEAN DEFAULT false,
|
|
version INT DEFAULT 1,
|
|
parent_id UUID REFERENCES assets.assets(id) ON DELETE SET NULL, -- For versions
|
|
created_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX idx_assets_tenant ON assets.assets(tenant_id);
|
|
CREATE INDEX idx_assets_collection ON assets.assets(collection_id);
|
|
CREATE INDEX idx_assets_job ON assets.assets(job_id);
|
|
CREATE INDEX idx_assets_mime ON assets.assets(mime_type);
|
|
|
|
-- ================================================================
|
|
-- ROW LEVEL SECURITY (RLS)
|
|
-- ================================================================
|
|
|
|
-- Enable RLS on all tenant-scoped tables
|
|
ALTER TABLE auth.tenants ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE auth.users ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE auth.sessions ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE auth.invitations ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE crm.clients ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE crm.brands ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE crm.products ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE projects.projects ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE projects.campaigns ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE generation.jobs ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE generation.custom_models ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE assets.collections ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE assets.assets ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Function to get current tenant from session variable
|
|
CREATE OR REPLACE FUNCTION auth.current_tenant_id()
|
|
RETURNS UUID AS $$
|
|
BEGIN
|
|
RETURN NULLIF(current_setting('app.current_tenant', true), '')::UUID;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- RLS Policies (example for clients, apply similar to all tables)
|
|
CREATE POLICY tenant_isolation_policy ON crm.clients
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON crm.brands
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON crm.products
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON projects.projects
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON projects.campaigns
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON generation.jobs
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON generation.custom_models
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON assets.collections
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
CREATE POLICY tenant_isolation_policy ON assets.assets
|
|
FOR ALL
|
|
USING (tenant_id = auth.current_tenant_id());
|
|
|
|
-- ================================================================
|
|
-- COMMENTS
|
|
-- ================================================================
|
|
|
|
COMMENT ON SCHEMA auth IS 'Authentication and authorization: users, tenants, sessions';
|
|
COMMENT ON SCHEMA crm IS 'Customer relationship management: clients, brands, products';
|
|
COMMENT ON SCHEMA projects IS 'Project management: projects, campaigns';
|
|
COMMENT ON SCHEMA generation IS 'AI generation: workflows, jobs, models';
|
|
COMMENT ON SCHEMA assets IS 'Digital asset management: files, collections';
|
|
|
|
COMMENT ON TABLE auth.tenants IS 'Organizations/companies using the platform';
|
|
COMMENT ON TABLE auth.users IS 'Platform users, scoped to tenants';
|
|
COMMENT ON TABLE generation.workflows IS 'AI generation workflow definitions';
|
|
COMMENT ON TABLE generation.jobs IS 'AI generation job queue and history';
|