-- ============================================================================
-- CONSTRUCTION Schema DDL - Gestión de Obras (COMPLETO)
-- Modulos: MAI-002, MAI-003, MAI-005, MAI-009, MAI-012
-- Version: 2.0.0
-- Fecha: 2025-12-08
-- ============================================================================
-- POLITICA: CARGA LIMPIA (ver DIRECTIVA-POLITICA-CARGA-LIMPIA.md)
-- Este archivo es parte de la fuente de verdad DDL.
-- ============================================================================

-- Verificar que ERP-Core está instalado
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'auth') THEN
        RAISE EXCEPTION 'Schema auth no existe. Ejecutar primero ERP-Core DDL';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'auth' AND tablename = 'tenants') THEN
        RAISE EXCEPTION 'Tabla auth.tenants no existe. ERP-Core debe estar instalado';
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'auth' AND tablename = 'users') THEN
        RAISE EXCEPTION 'Tabla auth.users no existe. ERP-Core debe estar instalado';
    END IF;
END $$;

-- Crear schema si no existe
CREATE SCHEMA IF NOT EXISTS construction;

-- ============================================================================
-- TYPES (ENUMs)
-- ============================================================================

DO $$ BEGIN
    CREATE TYPE construction.project_status AS ENUM (
        'draft', 'planning', 'in_progress', 'paused', 'completed', 'cancelled'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE construction.lot_status AS ENUM (
        'available', 'reserved', 'sold', 'under_construction', 'delivered', 'warranty'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE construction.prototype_type AS ENUM (
        'horizontal', 'vertical', 'commercial', 'mixed'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE construction.advance_status AS ENUM (
        'pending', 'captured', 'reviewed', 'approved', 'rejected'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE construction.quality_status AS ENUM (
        'pending', 'in_review', 'approved', 'rejected', 'rework'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE construction.contract_type AS ENUM (
        'fixed_price', 'unit_price', 'cost_plus', 'mixed'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE construction.contract_status AS ENUM (
        'draft', 'pending_approval', 'active', 'suspended', 'terminated', 'closed'
    );
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

-- ============================================================================
-- TABLES - ESTRUCTURA DE PROYECTO
-- ============================================================================

-- Tabla: fraccionamientos (desarrollo inmobiliario)
CREATE TABLE IF NOT EXISTS construction.fraccionamientos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    code VARCHAR(20) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    address TEXT,
    city VARCHAR(100),
    state VARCHAR(100),
    zip_code VARCHAR(10),
    location GEOMETRY(POINT, 4326),
    total_area_m2 DECIMAL(12,2),
    buildable_area_m2 DECIMAL(12,2),
    total_lots INTEGER DEFAULT 0,
    status construction.project_status NOT NULL DEFAULT 'draft',
    start_date DATE,
    expected_end_date DATE,
    actual_end_date DATE,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_fraccionamientos_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: etapas (fases del fraccionamiento)
CREATE TABLE IF NOT EXISTS construction.etapas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id) ON DELETE CASCADE,
    code VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    sequence INTEGER NOT NULL DEFAULT 1,
    total_lots INTEGER DEFAULT 0,
    status construction.project_status NOT NULL DEFAULT 'draft',
    start_date DATE,
    expected_end_date DATE,
    actual_end_date DATE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_etapas_code_fracc UNIQUE (fraccionamiento_id, code)
);

-- Tabla: manzanas (agrupación de lotes)
CREATE TABLE IF NOT EXISTS construction.manzanas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    etapa_id UUID NOT NULL REFERENCES construction.etapas(id) ON DELETE CASCADE,
    code VARCHAR(20) NOT NULL,
    name VARCHAR(100),
    total_lots INTEGER DEFAULT 0,
    polygon GEOMETRY(POLYGON, 4326),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_manzanas_code_etapa UNIQUE (etapa_id, code)
);

-- Tabla: prototipos (tipos de vivienda) - definida antes de lotes
CREATE TABLE IF NOT EXISTS construction.prototipos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    code VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    type construction.prototype_type NOT NULL DEFAULT 'horizontal',
    area_construction_m2 DECIMAL(10,2),
    area_terrain_m2 DECIMAL(10,2),
    bedrooms INTEGER DEFAULT 0,
    bathrooms DECIMAL(3,1) DEFAULT 0,
    parking_spaces INTEGER DEFAULT 0,
    floors INTEGER DEFAULT 1,
    base_price DECIMAL(14,2),
    blueprint_url VARCHAR(500),
    render_url VARCHAR(500),
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_prototipos_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: lotes (unidades vendibles horizontal)
CREATE TABLE IF NOT EXISTS construction.lotes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    manzana_id UUID NOT NULL REFERENCES construction.manzanas(id) ON DELETE CASCADE,
    prototipo_id UUID REFERENCES construction.prototipos(id),
    code VARCHAR(30) NOT NULL,
    official_number VARCHAR(50),
    area_m2 DECIMAL(10,2),
    front_m DECIMAL(8,2),
    depth_m DECIMAL(8,2),
    status construction.lot_status NOT NULL DEFAULT 'available',
    location GEOMETRY(POINT, 4326),
    polygon GEOMETRY(POLYGON, 4326),
    price_base DECIMAL(14,2),
    price_final DECIMAL(14,2),
    buyer_id UUID,
    sale_date DATE,
    delivery_date DATE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_lotes_code_manzana UNIQUE (manzana_id, code)
);

-- ============================================================================
-- TABLES - ESTRUCTURA VERTICAL (TORRES)
-- ============================================================================

-- Tabla: torres (edificios verticales)
CREATE TABLE IF NOT EXISTS construction.torres (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    etapa_id UUID NOT NULL REFERENCES construction.etapas(id) ON DELETE CASCADE,
    code VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    total_floors INTEGER NOT NULL DEFAULT 1,
    total_units INTEGER DEFAULT 0,
    status construction.project_status NOT NULL DEFAULT 'draft',
    location GEOMETRY(POINT, 4326),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_torres_code_etapa UNIQUE (etapa_id, code)
);

-- Tabla: niveles (pisos de torre)
CREATE TABLE IF NOT EXISTS construction.niveles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    torre_id UUID NOT NULL REFERENCES construction.torres(id) ON DELETE CASCADE,
    floor_number INTEGER NOT NULL,
    name VARCHAR(50),
    total_units INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_niveles_floor_torre UNIQUE (torre_id, floor_number)
);

-- Tabla: departamentos (unidades en torre)
CREATE TABLE IF NOT EXISTS construction.departamentos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    nivel_id UUID NOT NULL REFERENCES construction.niveles(id) ON DELETE CASCADE,
    prototipo_id UUID REFERENCES construction.prototipos(id),
    code VARCHAR(30) NOT NULL,
    unit_number VARCHAR(20) NOT NULL,
    area_m2 DECIMAL(10,2),
    status construction.lot_status NOT NULL DEFAULT 'available',
    price_base DECIMAL(14,2),
    price_final DECIMAL(14,2),
    buyer_id UUID,
    sale_date DATE,
    delivery_date DATE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_departamentos_code_nivel UNIQUE (nivel_id, code)
);

-- ============================================================================
-- TABLES - CONCEPTOS Y PRESUPUESTOS
-- ============================================================================

-- Tabla: conceptos (catálogo de conceptos de obra)
CREATE TABLE IF NOT EXISTS construction.conceptos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    parent_id UUID REFERENCES construction.conceptos(id),
    code VARCHAR(50) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    unit_id UUID,
    unit_price DECIMAL(12,4),
    is_composite BOOLEAN NOT NULL DEFAULT FALSE,
    level INTEGER NOT NULL DEFAULT 0,
    path VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_conceptos_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: presupuestos (presupuesto por prototipo/obra)
CREATE TABLE IF NOT EXISTS construction.presupuestos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id),
    prototipo_id UUID REFERENCES construction.prototipos(id),
    code VARCHAR(30) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    version INTEGER NOT NULL DEFAULT 1,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    total_amount DECIMAL(16,2) DEFAULT 0,
    currency_id UUID,
    approved_at TIMESTAMPTZ,
    approved_by UUID REFERENCES auth.users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_presupuestos_code_version UNIQUE (tenant_id, code, version)
);

-- Tabla: presupuesto_partidas (líneas del presupuesto)
CREATE TABLE IF NOT EXISTS construction.presupuesto_partidas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    presupuesto_id UUID NOT NULL REFERENCES construction.presupuestos(id) ON DELETE CASCADE,
    concepto_id UUID NOT NULL REFERENCES construction.conceptos(id),
    sequence INTEGER NOT NULL DEFAULT 0,
    quantity DECIMAL(12,4) NOT NULL DEFAULT 0,
    unit_price DECIMAL(12,4) NOT NULL DEFAULT 0,
    total_amount DECIMAL(14,2) GENERATED ALWAYS AS (quantity * unit_price) STORED,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_partidas_presupuesto_concepto UNIQUE (presupuesto_id, concepto_id)
);

-- ============================================================================
-- TABLES - AVANCES Y CONTROL DE OBRA
-- ============================================================================

-- Tabla: programa_obra (programa maestro)
CREATE TABLE IF NOT EXISTS construction.programa_obra (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    code VARCHAR(30) NOT NULL,
    name VARCHAR(255) NOT NULL,
    version INTEGER NOT NULL DEFAULT 1,
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_programa_code_version UNIQUE (tenant_id, code, version)
);

-- Tabla: programa_actividades (actividades del programa)
CREATE TABLE IF NOT EXISTS construction.programa_actividades (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    programa_id UUID NOT NULL REFERENCES construction.programa_obra(id) ON DELETE CASCADE,
    concepto_id UUID REFERENCES construction.conceptos(id),
    parent_id UUID REFERENCES construction.programa_actividades(id),
    name VARCHAR(255) NOT NULL,
    sequence INTEGER NOT NULL DEFAULT 0,
    planned_start DATE,
    planned_end DATE,
    planned_quantity DECIMAL(12,4) DEFAULT 0,
    planned_weight DECIMAL(8,4) DEFAULT 0,
    wbs_code VARCHAR(50),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: avances_obra (captura de avances)
CREATE TABLE IF NOT EXISTS construction.avances_obra (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    lote_id UUID REFERENCES construction.lotes(id),
    departamento_id UUID REFERENCES construction.departamentos(id),
    concepto_id UUID NOT NULL REFERENCES construction.conceptos(id),
    capture_date DATE NOT NULL,
    quantity_executed DECIMAL(12,4) NOT NULL DEFAULT 0,
    percentage_executed DECIMAL(5,2) DEFAULT 0,
    status construction.advance_status NOT NULL DEFAULT 'pending',
    notes TEXT,
    captured_by UUID NOT NULL REFERENCES auth.users(id),
    reviewed_by UUID REFERENCES auth.users(id),
    reviewed_at TIMESTAMPTZ,
    approved_by UUID REFERENCES auth.users(id),
    approved_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT chk_avances_lote_or_depto CHECK (
        (lote_id IS NOT NULL AND departamento_id IS NULL) OR
        (lote_id IS NULL AND departamento_id IS NOT NULL)
    )
);

-- Tabla: fotos_avance (evidencia fotográfica)
CREATE TABLE IF NOT EXISTS construction.fotos_avance (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    avance_id UUID NOT NULL REFERENCES construction.avances_obra(id) ON DELETE CASCADE,
    file_url VARCHAR(500) NOT NULL,
    file_name VARCHAR(255),
    file_size INTEGER,
    mime_type VARCHAR(50),
    description TEXT,
    location GEOMETRY(POINT, 4326),
    captured_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: bitacora_obra (registro de bitácora)
CREATE TABLE IF NOT EXISTS construction.bitacora_obra (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    entry_date DATE NOT NULL,
    entry_number INTEGER NOT NULL,
    weather VARCHAR(50),
    temperature_max DECIMAL(4,1),
    temperature_min DECIMAL(4,1),
    workers_count INTEGER DEFAULT 0,
    description TEXT NOT NULL,
    observations TEXT,
    incidents TEXT,
    registered_by UUID NOT NULL REFERENCES auth.users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_bitacora_fracc_number UNIQUE (fraccionamiento_id, entry_number)
);

-- ============================================================================
-- TABLES - CALIDAD Y POSTVENTA (MAI-009)
-- ============================================================================

-- Tabla: checklists (plantillas de verificación)
CREATE TABLE IF NOT EXISTS construction.checklists (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    code VARCHAR(30) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    prototipo_id UUID REFERENCES construction.prototipos(id),
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_checklists_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: checklist_items (items del checklist)
CREATE TABLE IF NOT EXISTS construction.checklist_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    checklist_id UUID NOT NULL REFERENCES construction.checklists(id) ON DELETE CASCADE,
    sequence INTEGER NOT NULL DEFAULT 0,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    is_required BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: inspecciones (inspecciones de calidad)
CREATE TABLE IF NOT EXISTS construction.inspecciones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    checklist_id UUID NOT NULL REFERENCES construction.checklists(id),
    lote_id UUID REFERENCES construction.lotes(id),
    departamento_id UUID REFERENCES construction.departamentos(id),
    inspection_date DATE NOT NULL,
    status construction.quality_status NOT NULL DEFAULT 'pending',
    inspector_id UUID NOT NULL REFERENCES auth.users(id),
    notes TEXT,
    approved_by UUID REFERENCES auth.users(id),
    approved_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: inspeccion_resultados (resultados por item)
CREATE TABLE IF NOT EXISTS construction.inspeccion_resultados (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    inspeccion_id UUID NOT NULL REFERENCES construction.inspecciones(id) ON DELETE CASCADE,
    checklist_item_id UUID NOT NULL REFERENCES construction.checklist_items(id),
    is_passed BOOLEAN,
    notes TEXT,
    photo_url VARCHAR(500),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id)
);

-- Tabla: tickets_postventa (tickets de garantía)
CREATE TABLE IF NOT EXISTS construction.tickets_postventa (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    lote_id UUID REFERENCES construction.lotes(id),
    departamento_id UUID REFERENCES construction.departamentos(id),
    ticket_number VARCHAR(30) NOT NULL,
    reported_date DATE NOT NULL,
    category VARCHAR(50),
    description TEXT NOT NULL,
    priority VARCHAR(20) DEFAULT 'medium',
    status VARCHAR(20) NOT NULL DEFAULT 'open',
    assigned_to UUID REFERENCES auth.users(id),
    resolution TEXT,
    resolved_at TIMESTAMPTZ,
    resolved_by UUID REFERENCES auth.users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_tickets_number_tenant UNIQUE (tenant_id, ticket_number)
);

-- ============================================================================
-- TABLES - CONTRATOS Y SUBCONTRATOS (MAI-012)
-- ============================================================================

-- Tabla: subcontratistas
CREATE TABLE IF NOT EXISTS construction.subcontratistas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    partner_id UUID,
    code VARCHAR(20) NOT NULL,
    name VARCHAR(255) NOT NULL,
    legal_name VARCHAR(255),
    tax_id VARCHAR(20),
    specialty VARCHAR(100),
    contact_name VARCHAR(100),
    contact_phone VARCHAR(20),
    contact_email VARCHAR(100),
    address TEXT,
    rating DECIMAL(3,2),
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_subcontratistas_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: contratos (contratos con subcontratistas)
CREATE TABLE IF NOT EXISTS construction.contratos (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    subcontratista_id UUID NOT NULL REFERENCES construction.subcontratistas(id),
    fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
    contract_number VARCHAR(30) NOT NULL,
    contract_type construction.contract_type NOT NULL DEFAULT 'unit_price',
    name VARCHAR(255) NOT NULL,
    description TEXT,
    start_date DATE NOT NULL,
    end_date DATE,
    total_amount DECIMAL(16,2),
    advance_percentage DECIMAL(5,2) DEFAULT 0,
    retention_percentage DECIMAL(5,2) DEFAULT 5,
    status construction.contract_status NOT NULL DEFAULT 'draft',
    signed_at TIMESTAMPTZ,
    signed_by UUID REFERENCES auth.users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id),
    CONSTRAINT uq_contratos_number_tenant UNIQUE (tenant_id, contract_number)
);

-- Tabla: contrato_partidas (líneas del contrato)
CREATE TABLE IF NOT EXISTS construction.contrato_partidas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    contrato_id UUID NOT NULL REFERENCES construction.contratos(id) ON DELETE CASCADE,
    concepto_id UUID NOT NULL REFERENCES construction.conceptos(id),
    quantity DECIMAL(12,4) NOT NULL DEFAULT 0,
    unit_price DECIMAL(12,4) NOT NULL DEFAULT 0,
    total_amount DECIMAL(14,2) GENERATED ALWAYS AS (quantity * unit_price) STORED,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,
    deleted_by UUID REFERENCES auth.users(id)
);

-- ============================================================================
-- INDICES
-- ============================================================================

-- Fraccionamientos
CREATE INDEX IF NOT EXISTS idx_fraccionamientos_tenant_id ON construction.fraccionamientos(tenant_id);
CREATE INDEX IF NOT EXISTS idx_fraccionamientos_status ON construction.fraccionamientos(status);
CREATE INDEX IF NOT EXISTS idx_fraccionamientos_code ON construction.fraccionamientos(code);

-- Etapas
CREATE INDEX IF NOT EXISTS idx_etapas_tenant_id ON construction.etapas(tenant_id);
CREATE INDEX IF NOT EXISTS idx_etapas_fraccionamiento_id ON construction.etapas(fraccionamiento_id);

-- Manzanas
CREATE INDEX IF NOT EXISTS idx_manzanas_tenant_id ON construction.manzanas(tenant_id);
CREATE INDEX IF NOT EXISTS idx_manzanas_etapa_id ON construction.manzanas(etapa_id);

-- Lotes
CREATE INDEX IF NOT EXISTS idx_lotes_tenant_id ON construction.lotes(tenant_id);
CREATE INDEX IF NOT EXISTS idx_lotes_manzana_id ON construction.lotes(manzana_id);
CREATE INDEX IF NOT EXISTS idx_lotes_prototipo_id ON construction.lotes(prototipo_id);
CREATE INDEX IF NOT EXISTS idx_lotes_status ON construction.lotes(status);

-- Torres
CREATE INDEX IF NOT EXISTS idx_torres_tenant_id ON construction.torres(tenant_id);
CREATE INDEX IF NOT EXISTS idx_torres_etapa_id ON construction.torres(etapa_id);

-- Niveles
CREATE INDEX IF NOT EXISTS idx_niveles_tenant_id ON construction.niveles(tenant_id);
CREATE INDEX IF NOT EXISTS idx_niveles_torre_id ON construction.niveles(torre_id);

-- Departamentos
CREATE INDEX IF NOT EXISTS idx_departamentos_tenant_id ON construction.departamentos(tenant_id);
CREATE INDEX IF NOT EXISTS idx_departamentos_nivel_id ON construction.departamentos(nivel_id);
CREATE INDEX IF NOT EXISTS idx_departamentos_status ON construction.departamentos(status);

-- Prototipos
CREATE INDEX IF NOT EXISTS idx_prototipos_tenant_id ON construction.prototipos(tenant_id);
CREATE INDEX IF NOT EXISTS idx_prototipos_type ON construction.prototipos(type);

-- Conceptos
CREATE INDEX IF NOT EXISTS idx_conceptos_tenant_id ON construction.conceptos(tenant_id);
CREATE INDEX IF NOT EXISTS idx_conceptos_parent_id ON construction.conceptos(parent_id);
CREATE INDEX IF NOT EXISTS idx_conceptos_code ON construction.conceptos(code);

-- Presupuestos
CREATE INDEX IF NOT EXISTS idx_presupuestos_tenant_id ON construction.presupuestos(tenant_id);
CREATE INDEX IF NOT EXISTS idx_presupuestos_fraccionamiento_id ON construction.presupuestos(fraccionamiento_id);

-- Avances
CREATE INDEX IF NOT EXISTS idx_avances_tenant_id ON construction.avances_obra(tenant_id);
CREATE INDEX IF NOT EXISTS idx_avances_lote_id ON construction.avances_obra(lote_id);
CREATE INDEX IF NOT EXISTS idx_avances_concepto_id ON construction.avances_obra(concepto_id);
CREATE INDEX IF NOT EXISTS idx_avances_capture_date ON construction.avances_obra(capture_date);

-- Bitacora
CREATE INDEX IF NOT EXISTS idx_bitacora_tenant_id ON construction.bitacora_obra(tenant_id);
CREATE INDEX IF NOT EXISTS idx_bitacora_fraccionamiento_id ON construction.bitacora_obra(fraccionamiento_id);

-- Inspecciones
CREATE INDEX IF NOT EXISTS idx_inspecciones_tenant_id ON construction.inspecciones(tenant_id);
CREATE INDEX IF NOT EXISTS idx_inspecciones_status ON construction.inspecciones(status);

-- Tickets
CREATE INDEX IF NOT EXISTS idx_tickets_tenant_id ON construction.tickets_postventa(tenant_id);
CREATE INDEX IF NOT EXISTS idx_tickets_status ON construction.tickets_postventa(status);

-- Subcontratistas
CREATE INDEX IF NOT EXISTS idx_subcontratistas_tenant_id ON construction.subcontratistas(tenant_id);

-- Contratos
CREATE INDEX IF NOT EXISTS idx_contratos_tenant_id ON construction.contratos(tenant_id);
CREATE INDEX IF NOT EXISTS idx_contratos_subcontratista_id ON construction.contratos(subcontratista_id);
CREATE INDEX IF NOT EXISTS idx_contratos_fraccionamiento_id ON construction.contratos(fraccionamiento_id);

-- ============================================================================
-- ROW LEVEL SECURITY (RLS)
-- ============================================================================

ALTER TABLE construction.fraccionamientos ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.etapas ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.manzanas ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.lotes ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.torres ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.niveles ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.departamentos ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.prototipos ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.conceptos ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.presupuestos ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.presupuesto_partidas ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.programa_obra ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.programa_actividades ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.avances_obra ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.fotos_avance ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.bitacora_obra ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.checklists ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.checklist_items ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.inspecciones ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.inspeccion_resultados ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.tickets_postventa ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.subcontratistas ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.contratos ENABLE ROW LEVEL SECURITY;
ALTER TABLE construction.contrato_partidas ENABLE ROW LEVEL SECURITY;

-- Policies de tenant isolation usando current_setting
DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_fraccionamientos ON construction.fraccionamientos;
    CREATE POLICY tenant_isolation_fraccionamientos ON construction.fraccionamientos
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_etapas ON construction.etapas;
    CREATE POLICY tenant_isolation_etapas ON construction.etapas
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_manzanas ON construction.manzanas;
    CREATE POLICY tenant_isolation_manzanas ON construction.manzanas
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_lotes ON construction.lotes;
    CREATE POLICY tenant_isolation_lotes ON construction.lotes
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_torres ON construction.torres;
    CREATE POLICY tenant_isolation_torres ON construction.torres
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_niveles ON construction.niveles;
    CREATE POLICY tenant_isolation_niveles ON construction.niveles
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_departamentos ON construction.departamentos;
    CREATE POLICY tenant_isolation_departamentos ON construction.departamentos
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_prototipos ON construction.prototipos;
    CREATE POLICY tenant_isolation_prototipos ON construction.prototipos
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_conceptos ON construction.conceptos;
    CREATE POLICY tenant_isolation_conceptos ON construction.conceptos
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_presupuestos ON construction.presupuestos;
    CREATE POLICY tenant_isolation_presupuestos ON construction.presupuestos
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_presupuesto_partidas ON construction.presupuesto_partidas;
    CREATE POLICY tenant_isolation_presupuesto_partidas ON construction.presupuesto_partidas
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_programa_obra ON construction.programa_obra;
    CREATE POLICY tenant_isolation_programa_obra ON construction.programa_obra
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_programa_actividades ON construction.programa_actividades;
    CREATE POLICY tenant_isolation_programa_actividades ON construction.programa_actividades
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_avances_obra ON construction.avances_obra;
    CREATE POLICY tenant_isolation_avances_obra ON construction.avances_obra
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_fotos_avance ON construction.fotos_avance;
    CREATE POLICY tenant_isolation_fotos_avance ON construction.fotos_avance
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_bitacora_obra ON construction.bitacora_obra;
    CREATE POLICY tenant_isolation_bitacora_obra ON construction.bitacora_obra
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_checklists ON construction.checklists;
    CREATE POLICY tenant_isolation_checklists ON construction.checklists
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_checklist_items ON construction.checklist_items;
    CREATE POLICY tenant_isolation_checklist_items ON construction.checklist_items
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_inspecciones ON construction.inspecciones;
    CREATE POLICY tenant_isolation_inspecciones ON construction.inspecciones
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_inspeccion_resultados ON construction.inspeccion_resultados;
    CREATE POLICY tenant_isolation_inspeccion_resultados ON construction.inspeccion_resultados
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_tickets_postventa ON construction.tickets_postventa;
    CREATE POLICY tenant_isolation_tickets_postventa ON construction.tickets_postventa
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_subcontratistas ON construction.subcontratistas;
    CREATE POLICY tenant_isolation_subcontratistas ON construction.subcontratistas
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_contratos ON construction.contratos;
    CREATE POLICY tenant_isolation_contratos ON construction.contratos
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

DO $$ BEGIN
    DROP POLICY IF EXISTS tenant_isolation_contrato_partidas ON construction.contrato_partidas;
    CREATE POLICY tenant_isolation_contrato_partidas ON construction.contrato_partidas
        FOR ALL USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
EXCEPTION WHEN undefined_object THEN NULL; END $$;

-- ============================================================================
-- COMENTARIOS
-- ============================================================================

COMMENT ON SCHEMA construction IS 'Schema de construcción: obras, lotes, avances, calidad, contratos';
COMMENT ON TABLE construction.fraccionamientos IS 'Desarrollos inmobiliarios/fraccionamientos';
COMMENT ON TABLE construction.etapas IS 'Etapas/fases de un fraccionamiento';
COMMENT ON TABLE construction.manzanas IS 'Manzanas dentro de una etapa';
COMMENT ON TABLE construction.lotes IS 'Lotes/terrenos vendibles (horizontal)';
COMMENT ON TABLE construction.torres IS 'Torres/edificios (vertical)';
COMMENT ON TABLE construction.niveles IS 'Pisos de una torre';
COMMENT ON TABLE construction.departamentos IS 'Departamentos/unidades en torre';
COMMENT ON TABLE construction.prototipos IS 'Tipos de vivienda/prototipos';
COMMENT ON TABLE construction.conceptos IS 'Catálogo de conceptos de obra';
COMMENT ON TABLE construction.presupuestos IS 'Presupuestos por prototipo u obra';
COMMENT ON TABLE construction.avances_obra IS 'Captura de avances físicos';
COMMENT ON TABLE construction.bitacora_obra IS 'Bitácora diaria de obra';
COMMENT ON TABLE construction.checklists IS 'Plantillas de verificación';
COMMENT ON TABLE construction.inspecciones IS 'Inspecciones de calidad';
COMMENT ON TABLE construction.tickets_postventa IS 'Tickets de garantía';
COMMENT ON TABLE construction.subcontratistas IS 'Catálogo de subcontratistas';
COMMENT ON TABLE construction.contratos IS 'Contratos con subcontratistas';

-- ============================================================================
-- FIN DEL SCHEMA CONSTRUCTION
-- Total tablas: 24
-- ============================================================================
