-- =====================================================
-- SCHEMA: construction
-- PROPOSITO: Obras, proyectos, lotes, prototipos, avances
-- MODULOS: MAI-002, MAI-003, MAI-005, MAI-009, MAI-012
-- FECHA: 2025-11-24
-- ESPECIFICO: 100% construccion
-- =====================================================

-- Crear schema
CREATE SCHEMA IF NOT EXISTS construction;

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

CREATE TYPE construction.project_status AS ENUM (
  'draft',           -- Borrador
  'planning',        -- En planeacion
  'in_progress',     -- En ejecucion
  'paused',          -- Pausado
  'completed',       -- Completado
  'cancelled'        -- Cancelado
);

CREATE TYPE construction.lot_status AS ENUM (
  'available',       -- Disponible para venta
  'reserved',        -- Reservado
  'sold',            -- Vendido
  'under_construction', -- En construccion
  'delivered',       -- Entregado
  'warranty'         -- En periodo de garantia
);

CREATE TYPE construction.prototype_type AS ENUM (
  'horizontal',      -- Casa horizontal
  'vertical',        -- Departamento en torre
  'commercial',      -- Local comercial
  'mixed'            -- Uso mixto
);

CREATE TYPE construction.advance_status AS ENUM (
  'pending',         -- Pendiente captura
  'captured',        -- Capturado
  'reviewed',        -- Revisado
  'approved',        -- Aprobado
  'rejected'         -- Rechazado
);

CREATE TYPE construction.quality_status AS ENUM (
  'pending',         -- Pendiente revision
  'in_review',       -- En revision
  'approved',        -- Aprobado
  'rejected',        -- Rechazado
  'rework'           -- Requiere retrabajo
);

CREATE TYPE construction.contract_type AS ENUM (
  'fixed_price',     -- Precio fijo
  'unit_price',      -- Precio unitario
  'cost_plus',       -- Costo + porcentaje
  'mixed'            -- Mixto
);

CREATE TYPE construction.contract_status AS ENUM (
  'draft',           -- Borrador
  'pending_approval', -- Pendiente aprobacion
  'active',          -- Activo
  'suspended',       -- Suspendido
  'terminated',      -- Terminado
  'closed'           -- Cerrado
);

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

-- Tabla: fraccionamientos (desarrollo inmobiliario)
CREATE TABLE 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), -- PostGIS
  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 '{}',

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_fraccionamientos_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: etapas (fases del fraccionamiento)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_etapas_code_fracc UNIQUE (fraccionamiento_id, code)
);

-- Tabla: manzanas (agrupacion de lotes)
CREATE TABLE 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), -- PostGIS

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_manzanas_code_etapa UNIQUE (etapa_id, code)
);

-- Tabla: lotes (unidades vendibles)
CREATE TABLE 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), -- Numero oficial catastral
  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, -- FK a cliente/derechohabiente
  sale_date DATE,
  delivery_date DATE,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  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 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),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_torres_code_etapa UNIQUE (etapa_id, code)
);

-- Tabla: niveles (pisos de torre)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_niveles_floor_torre UNIQUE (torre_id, floor_number)
);

-- Tabla: departamentos (unidades en torre)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_departamentos_code_nivel UNIQUE (nivel_id, code)
);

-- =====================================================
-- TABLES - PROTOTIPOS Y PRESUPUESTOS
-- =====================================================

-- Tabla: prototipos (tipos de vivienda)
CREATE TABLE 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 '{}', -- Especificaciones tecnicas

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_prototipos_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: conceptos (catalogo de conceptos de obra)
CREATE TABLE 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, -- FK a core.uom
  unit_price DECIMAL(12,4),
  is_composite BOOLEAN NOT NULL DEFAULT FALSE,
  level INTEGER NOT NULL DEFAULT 0, -- Nivel en jerarquia
  path VARCHAR(500), -- Path materializado para queries

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_conceptos_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: presupuestos (presupuesto por prototipo/obra)
CREATE TABLE 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, -- FK a core.currencies
  approved_at TIMESTAMP,
  approved_by UUID REFERENCES auth.users(id),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_presupuestos_code_version UNIQUE (tenant_id, code, version)
);

-- Tabla: presupuesto_partidas (lineas del presupuesto)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  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 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  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 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, -- Peso ponderado %
  wbs_code VARCHAR(50), -- Work Breakdown Structure

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: avances_obra (captura de avances)
CREATE TABLE 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 TIMESTAMP,
  approved_by UUID REFERENCES auth.users(id),
  approved_at TIMESTAMP,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  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 fotografica)
CREATE TABLE 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), -- GPS donde se tomo
  captured_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: bitacora_obra (registro de bitacora)
CREATE TABLE 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),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  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 verificacion)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_checklists_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: checklist_items (items del checklist)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: inspecciones (inspecciones de calidad)
CREATE TABLE 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 TIMESTAMP,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id)
);

-- Tabla: inspeccion_resultados (resultados por item)
CREATE TABLE 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),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id)
);

-- Tabla: tickets_postventa (tickets de garantia)
CREATE TABLE 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), -- plomeria, electricidad, estructura, etc.
  description TEXT NOT NULL,
  priority VARCHAR(20) DEFAULT 'medium', -- low, medium, high, urgent
  status VARCHAR(20) NOT NULL DEFAULT 'open', -- open, in_progress, resolved, closed
  assigned_to UUID REFERENCES auth.users(id),
  resolution TEXT,
  resolved_at TIMESTAMP,
  resolved_by UUID REFERENCES auth.users(id),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  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 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, -- FK a core.partners
  code VARCHAR(20) NOT NULL,
  name VARCHAR(255) NOT NULL,
  legal_name VARCHAR(255),
  tax_id VARCHAR(20),
  specialty VARCHAR(100), -- Especialidad: alba~nileria, electricidad, etc.
  contact_name VARCHAR(100),
  contact_phone VARCHAR(20),
  contact_email VARCHAR(100),
  address TEXT,
  rating DECIMAL(3,2), -- Calificacion 0-5
  is_active BOOLEAN NOT NULL DEFAULT TRUE,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_subcontratistas_code_tenant UNIQUE (tenant_id, code)
);

-- Tabla: contratos (contratos con subcontratistas)
CREATE TABLE 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, -- % anticipo
  retention_percentage DECIMAL(5,2) DEFAULT 5, -- % retencion
  status construction.contract_status NOT NULL DEFAULT 'draft',
  signed_at TIMESTAMP,
  signed_by UUID REFERENCES auth.users(id),

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id),

  CONSTRAINT uq_contratos_number_tenant UNIQUE (tenant_id, contract_number)
);

-- Tabla: contrato_partidas (lineas del contrato)
CREATE TABLE 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,

  -- Auditoria
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  created_by UUID REFERENCES auth.users(id),
  updated_at TIMESTAMP,
  updated_by UUID REFERENCES auth.users(id),
  deleted_at TIMESTAMP,
  deleted_by UUID REFERENCES auth.users(id)
);

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

-- Fraccionamientos
CREATE INDEX idx_fraccionamientos_tenant_id ON construction.fraccionamientos(tenant_id);
CREATE INDEX idx_fraccionamientos_status ON construction.fraccionamientos(status);
CREATE INDEX idx_fraccionamientos_code ON construction.fraccionamientos(code);
CREATE INDEX idx_fraccionamientos_active ON construction.fraccionamientos(tenant_id) WHERE deleted_at IS NULL;

-- Etapas
CREATE INDEX idx_etapas_tenant_id ON construction.etapas(tenant_id);
CREATE INDEX idx_etapas_fraccionamiento_id ON construction.etapas(fraccionamiento_id);
CREATE INDEX idx_etapas_status ON construction.etapas(status);

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

-- Lotes
CREATE INDEX idx_lotes_tenant_id ON construction.lotes(tenant_id);
CREATE INDEX idx_lotes_manzana_id ON construction.lotes(manzana_id);
CREATE INDEX idx_lotes_prototipo_id ON construction.lotes(prototipo_id);
CREATE INDEX idx_lotes_status ON construction.lotes(status);
CREATE INDEX idx_lotes_buyer_id ON construction.lotes(buyer_id) WHERE buyer_id IS NOT NULL;

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

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

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

-- Prototipos
CREATE INDEX idx_prototipos_tenant_id ON construction.prototipos(tenant_id);
CREATE INDEX idx_prototipos_type ON construction.prototipos(type);
CREATE INDEX idx_prototipos_active ON construction.prototipos(tenant_id) WHERE is_active = TRUE;

-- Conceptos
CREATE INDEX idx_conceptos_tenant_id ON construction.conceptos(tenant_id);
CREATE INDEX idx_conceptos_parent_id ON construction.conceptos(parent_id);
CREATE INDEX idx_conceptos_code ON construction.conceptos(code);
CREATE INDEX idx_conceptos_path ON construction.conceptos(path);

-- Presupuestos
CREATE INDEX idx_presupuestos_tenant_id ON construction.presupuestos(tenant_id);
CREATE INDEX idx_presupuestos_fraccionamiento_id ON construction.presupuestos(fraccionamiento_id);
CREATE INDEX idx_presupuestos_prototipo_id ON construction.presupuestos(prototipo_id);

-- Avances
CREATE INDEX idx_avances_tenant_id ON construction.avances_obra(tenant_id);
CREATE INDEX idx_avances_lote_id ON construction.avances_obra(lote_id);
CREATE INDEX idx_avances_departamento_id ON construction.avances_obra(departamento_id);
CREATE INDEX idx_avances_concepto_id ON construction.avances_obra(concepto_id);
CREATE INDEX idx_avances_capture_date ON construction.avances_obra(capture_date);
CREATE INDEX idx_avances_status ON construction.avances_obra(status);

-- Bitacora
CREATE INDEX idx_bitacora_tenant_id ON construction.bitacora_obra(tenant_id);
CREATE INDEX idx_bitacora_fraccionamiento_id ON construction.bitacora_obra(fraccionamiento_id);
CREATE INDEX idx_bitacora_entry_date ON construction.bitacora_obra(entry_date);

-- Inspecciones
CREATE INDEX idx_inspecciones_tenant_id ON construction.inspecciones(tenant_id);
CREATE INDEX idx_inspecciones_lote_id ON construction.inspecciones(lote_id);
CREATE INDEX idx_inspecciones_status ON construction.inspecciones(status);

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

-- Subcontratistas
CREATE INDEX idx_subcontratistas_tenant_id ON construction.subcontratistas(tenant_id);
CREATE INDEX idx_subcontratistas_specialty ON construction.subcontratistas(specialty);

-- Contratos
CREATE INDEX idx_contratos_tenant_id ON construction.contratos(tenant_id);
CREATE INDEX idx_contratos_subcontratista_id ON construction.contratos(subcontratista_id);
CREATE INDEX idx_contratos_fraccionamiento_id ON construction.contratos(fraccionamiento_id);
CREATE INDEX idx_contratos_status ON construction.contratos(status);

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

-- Habilitar RLS en todas las tablas
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
CREATE POLICY tenant_isolation_fraccionamientos ON construction.fraccionamientos
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_etapas ON construction.etapas
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_manzanas ON construction.manzanas
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_lotes ON construction.lotes
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_torres ON construction.torres
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_niveles ON construction.niveles
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_departamentos ON construction.departamentos
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_prototipos ON construction.prototipos
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_conceptos ON construction.conceptos
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_presupuestos ON construction.presupuestos
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_presupuesto_partidas ON construction.presupuesto_partidas
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_programa_obra ON construction.programa_obra
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_programa_actividades ON construction.programa_actividades
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_avances_obra ON construction.avances_obra
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_fotos_avance ON construction.fotos_avance
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_bitacora_obra ON construction.bitacora_obra
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_checklists ON construction.checklists
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_checklist_items ON construction.checklist_items
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_inspecciones ON construction.inspecciones
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_inspeccion_resultados ON construction.inspeccion_resultados
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_tickets_postventa ON construction.tickets_postventa
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_subcontratistas ON construction.subcontratistas
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_contratos ON construction.contratos
  USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation_contrato_partidas ON construction.contrato_partidas
  USING (tenant_id = get_current_tenant_id());

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

COMMENT ON SCHEMA construction IS 'Schema especifico de construccion: obras, lotes, avances, calidad';
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 (vertical)';
COMMENT ON TABLE construction.prototipos IS 'Tipos de vivienda/prototipos';
COMMENT ON TABLE construction.conceptos IS 'Catalogo 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 fisicos de obra';
COMMENT ON TABLE construction.bitacora_obra IS 'Bitacora diaria de obra';
COMMENT ON TABLE construction.checklists IS 'Plantillas de verificacion de calidad';
COMMENT ON TABLE construction.inspecciones IS 'Inspecciones de calidad';
COMMENT ON TABLE construction.tickets_postventa IS 'Tickets de garantia/postventa';
COMMENT ON TABLE construction.subcontratistas IS 'Catalogo de subcontratistas';
COMMENT ON TABLE construction.contratos IS 'Contratos con subcontratistas';

-- =====================================================
-- FIN DEL SCHEMA CONSTRUCTION
-- =====================================================
