-- ============================================================================ -- CONSTRUCTION Schema DDL - Gestion de Obras -- Modulo: MAA-001 a MAA-006 (Fundamentos de Construccion) -- Version: 1.0.0 -- Fecha: 2025-12-06 -- ============================================================================ -- POLITICA: CARGA LIMPIA (ver DIRECTIVA-POLITICA-CARGA-LIMPIA.md) -- Este archivo es parte de la fuente de verdad DDL. -- ============================================================================ -- Verificar que init-database.sql se ejecuto DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'core') THEN RAISE EXCEPTION 'Schema core no existe. Ejecutar primero init-scripts/01-init-database.sql'; END IF; END $$; -- Crear schema si no existe CREATE SCHEMA IF NOT EXISTS construction; -- Configurar search_path SET search_path TO construction, core, core_shared, public; -- ============================================================================ -- TABLAS BASE MINIMAS (requeridas por otros modulos como HSE) -- ============================================================================ -- Tabla: Proyectos (desarrollo inmobiliario) CREATE TABLE IF NOT EXISTS construction.proyectos ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES core.tenants(id), codigo VARCHAR(20) NOT NULL, nombre VARCHAR(200) NOT NULL, descripcion TEXT, direccion TEXT, ciudad VARCHAR(100), estado VARCHAR(100), fecha_inicio DATE, fecha_fin_estimada DATE, estado_proyecto VARCHAR(20) NOT NULL DEFAULT 'activo', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_by UUID REFERENCES core.users(id), CONSTRAINT uq_proyectos_codigo UNIQUE (tenant_id, codigo) ); -- Tabla: Fraccionamientos (obras dentro de un proyecto) CREATE TABLE IF NOT EXISTS construction.fraccionamientos ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES core.tenants(id), proyecto_id UUID NOT NULL REFERENCES construction.proyectos(id), codigo VARCHAR(20) NOT NULL, nombre VARCHAR(200) NOT NULL, descripcion TEXT, direccion TEXT, ubicacion_geo GEOMETRY(Point, 4326), fecha_inicio DATE, fecha_fin_estimada DATE, estado VARCHAR(20) NOT NULL DEFAULT 'activo', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_by UUID REFERENCES core.users(id), CONSTRAINT uq_fraccionamientos_codigo UNIQUE (tenant_id, codigo) ); -- ============================================================================ -- INDICES -- ============================================================================ CREATE INDEX IF NOT EXISTS idx_proyectos_tenant ON construction.proyectos(tenant_id); CREATE INDEX IF NOT EXISTS idx_fraccionamientos_tenant ON construction.fraccionamientos(tenant_id); CREATE INDEX IF NOT EXISTS idx_fraccionamientos_proyecto ON construction.fraccionamientos(proyecto_id); -- ============================================================================ -- ROW LEVEL SECURITY -- ============================================================================ ALTER TABLE construction.proyectos ENABLE ROW LEVEL SECURITY; ALTER TABLE construction.fraccionamientos ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_proyectos ON construction.proyectos FOR ALL USING (tenant_id = current_setting('app.current_tenant', true)::UUID); CREATE POLICY tenant_isolation_fraccionamientos ON construction.fraccionamientos FOR ALL USING (tenant_id = current_setting('app.current_tenant', true)::UUID); -- ============================================================================ -- TRIGGERS -- ============================================================================ CREATE TRIGGER trg_proyectos_updated_at BEFORE UPDATE ON construction.proyectos FOR EACH ROW EXECUTE FUNCTION core_shared.set_updated_at(); CREATE TRIGGER trg_fraccionamientos_updated_at BEFORE UPDATE ON construction.fraccionamientos FOR EACH ROW EXECUTE FUNCTION core_shared.set_updated_at(); -- ============================================================================ -- COMENTARIOS -- ============================================================================ COMMENT ON TABLE construction.proyectos IS 'Proyectos de desarrollo inmobiliario'; COMMENT ON TABLE construction.fraccionamientos IS 'Fraccionamientos/obras dentro de un proyecto'; -- ============================================================================ -- FIN -- ============================================================================