# FASE 5: Análisis de Dependencias - ERP Construcción

**Proyecto:** erp-construccion
**Fecha:** 2026-01-04
**Estado:** Completado
**Base:** FASE-4-VALIDACION-PLAN.md

---

## 1. Inventario de Schemas Existentes

### 1.1 Estructura Actual

| # | Archivo DDL | Schema | Tablas | Líneas |
|---|-------------|--------|--------|--------|
| 1 | 01-construction-schema-ddl.sql | construction | 24 | 903 |
| 2 | 02-hr-schema-ddl.sql | hr | 3 | 156 |
| 3 | 03-hse-schema-ddl.sql | hse | 58 | 1,268 |
| 4 | 04-estimates-schema-ddl.sql | estimates | 8 | 415 |
| 5 | 05-infonavit-schema-ddl.sql | infonavit | 8 | 413 |
| 6 | 06-inventory-ext-schema-ddl.sql | inventory | 4 | 213 |
| 7 | 07-purchase-ext-schema-ddl.sql | purchase | 5 | 227 |
| **Total** | | **7 schemas** | **110** | **3,595** |

### 1.2 Orden de Ejecución Actual

```
1. auth (ERP-Core)
2. core (ERP-Core)
3. construction (01-construction-schema-ddl.sql)
4. hr (02-hr-schema-ddl.sql)
5. hse (03-hse-schema-ddl.sql)
6. estimates (04-estimates-schema-ddl.sql)
7. infonavit (05-infonavit-schema-ddl.sql)
8. inventory (06-inventory-ext-schema-ddl.sql)
9. purchase (07-purchase-ext-schema-ddl.sql)
```

---

## 2. Dependencias con ERP-Core

### 2.1 Tablas Core Requeridas

| Tabla Core | Usado Por | Estado |
|------------|-----------|--------|
| auth.tenants | Todas las tablas | ✅ Requerido |
| auth.users | created_by, approved_by, etc. | ✅ Requerido |
| core.partners | Proveedores, contratistas | ⚠️ Verificar |
| core.companies | company_id opcional | ⚠️ Verificar |
| core.currencies | currency_id | ⚠️ Verificar |
| core.countries | origin_country_id | ⚠️ Verificar |
| core.addresses | address_id | ⚠️ Verificar |
| financial.payment_terms | payment_term_id | ⚠️ Verificar |
| financial.accounts | account_id | ⚠️ Verificar |
| inventory.products | product_id | ⚠️ Verificar |
| inventory.categories | category_id | ⚠️ Verificar |
| inventory.locations | location_id | ⚠️ Verificar |
| inventory.warehouses | warehouse_id | ⚠️ Verificar |
| inventory.stock_pickings | picking_id | ⚠️ Verificar |
| inventory.stock_moves | stock_move_id | ⚠️ Verificar |
| hr.contracts | contract_id | ⚠️ Verificar |
| projects.projects | project_id | ⚠️ Verificar |

### 2.2 Verificación de Existencia

**Acción:** Las FKs a tablas ERP-Core deben usar referencias opcionales (sin ON DELETE CASCADE) para permitir instalación sin ERP-Core completo.

**Patrón Recomendado:**
```sql
-- En lugar de:
partner_id UUID NOT NULL REFERENCES core.partners(id)

-- Usar:
partner_id UUID -- FK a core.partners (ERP-Core) - opcional
```

---

## 3. Dependencias Internas del Proyecto

### 3.1 Mapa de Dependencias

```
construction.fraccionamientos
  ├── construction.etapas
  │   ├── construction.manzanas
  │   │   └── construction.lotes
  │   └── construction.torres
  │       └── construction.niveles
  │           └── construction.departamentos
  ├── construction.presupuestos
  │   └── construction.presupuesto_partidas
  ├── construction.programa_obra
  │   └── construction.programa_actividades
  ├── construction.bitacora_obra
  ├── inventory.almacenes_proyecto
  └── hr.employee_fraccionamientos
```

### 3.2 HALLAZGO CRÍTICO

**No existe tabla `construction.proyectos`**

El proyecto usa `construction.fraccionamientos` como entidad principal de proyecto.

**Impacto:**
- El plan FASE-3 referencia `construction.proyectos`
- Debe cambiarse a `construction.fraccionamientos`
- La tabla `avance_programado` debe referenciar `fraccionamiento_id`

**Resolución:**
```sql
-- Cambiar de:
proyecto_id UUID REFERENCES construction.proyectos(id)

-- A:
fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id)
```

### 3.3 Tabla de Partidas

**Hallazgo:** No existe tabla `construction.partidas` individual.

**Tablas relacionadas existentes:**
- `construction.presupuesto_partidas` - Líneas de presupuesto
- `construction.contrato_partidas` - Líneas de contrato

**Resolución para trigger de conteo:**
- El trigger `update_proyecto_partida_count` no aplica directamente
- Adaptar para contar `presupuesto_partidas` o `avances_obra`

---

## 4. Análisis de FK por Tabla Nueva

### 4.1 financial.payment_term_lines

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| tenant_id | auth.tenants | ✅ | ✅ |
| payment_term_id | financial.payment_terms | ❌ | ⚠️ Verificar |

**Acción:** Hacer FK opcional o crear tabla si no existe.

### 4.2 financial.incoterms

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| (ninguna) | - | - | Tabla catálogo standalone |

**Acción:** Sin dependencias.

### 4.3 financial.payment_methods

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| tenant_id | auth.tenants | ✅ | ✅ |

**Acción:** Sin problemas.

### 4.4 financial.reconcile_models

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| tenant_id | auth.tenants | ✅ | ✅ |
| company_id | core.companies | ❌ | ⚠️ Verificar |

**Acción:** FK opcional a core.companies.

### 4.5 financial.reconcile_model_lines

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| model_id | financial.reconcile_models | Crear primero | - |
| account_id | financial.accounts | ❌ | ⚠️ Verificar |

**Acción:** Crear reconcile_models antes. FK opcional a accounts.

### 4.6 projects.collaborators

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| tenant_id | auth.tenants | ✅ | ✅ |
| project_id | projects.projects | ❌ | ⚠️ Verificar |
| partner_id | core.partners | ❌ | ⚠️ Verificar |
| user_id | auth.users | ✅ | ✅ |

**Acción:**
- Adaptar para usar `fraccionamiento_id` en lugar de `project_id`
- FK opcional a core.partners

### 4.7 projects.ratings

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| tenant_id | auth.tenants | ✅ | ✅ |
| partner_id | core.partners | ❌ | ⚠️ Verificar |

**Acción:** FK opcional.

### 4.8 construction.avance_programado

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| fraccionamiento_id | construction.fraccionamientos | ✅ | Adaptado de proyecto_id |

**Acción:** ✅ Sin problemas.

### 4.9 construction.ubicaciones_obra

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| work_location_id | hr.work_locations | Crear primero | |
| fraccionamiento_id | construction.fraccionamientos | ✅ | Adaptado |

**Acción:** Crear hr.work_locations antes.

### 4.10 hr.work_locations

| FK | Tabla Destino | Existe en Proyecto | Existe en Core |
|----|---------------|--------------------|----------------|
| tenant_id | auth.tenants | ✅ | ✅ |
| company_id | core.companies | ❌ | ⚠️ Opcional |
| address_id | core.addresses | ❌ | ⚠️ Opcional |

**Acción:** FKs opcionales.

### 4.11 hr.skill_types, skills, skill_levels

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| skill_type_id | hr.skill_types | Crear primero | Orden: types → skills/levels |

**Acción:** Crear skill_types antes que skills y skill_levels.

### 4.12 hr.employee_skills

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| employee_id | hr.employees | ✅ | |
| skill_id | hr.skills | Crear primero | |
| skill_level_id | hr.skill_levels | Crear primero | |

**Acción:** Crear skills y levels antes.

### 4.13 hr.expense_sheets

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| company_id | core.companies | ❌ | ⚠️ Opcional |
| employee_id | hr.employees | ✅ | |
| currency_id | core.currencies | ❌ | ⚠️ Opcional |

**Acción:** FKs opcionales a core.

### 4.14 hr.expenses

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| expense_sheet_id | hr.expense_sheets | Crear primero | |
| employee_id | hr.employees | ✅ | |
| product_id | inventory.products | ❌ | ⚠️ Opcional |
| currency_id | core.currencies | ❌ | ⚠️ Opcional |

**Acción:** Crear expense_sheets antes. FKs opcionales a core/inventory.

### 4.15 hr.employee_resume_lines

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| employee_id | hr.employees | ✅ | |

**Acción:** ✅ Sin problemas.

### 4.16 hr.payslip_structures

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |

**Acción:** ✅ Sin problemas.

### 4.17 hr.payslips

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| company_id | core.companies | ❌ | ⚠️ Opcional |
| employee_id | hr.employees | ✅ | |
| contract_id | hr.contracts | ❌ | ⚠️ Verificar |
| structure_id | hr.payslip_structures | Crear primero | |

**Acción:** Crear structures antes. FK opcional a contracts.

### 4.18 hr.payslip_lines

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| payslip_id | hr.payslips | Crear primero | |

**Acción:** Crear payslips antes.

### 4.19 inventory.* (nuevas)

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| location_id | inventory.locations | ❌ | ⚠️ Opcional (Core) |
| product_id | inventory.products | ❌ | ⚠️ Opcional (Core) |
| category_id | inventory.categories | ❌ | ⚠️ Opcional (Core) |

**Acción:** FKs opcionales a tablas inventory de Core.

### 4.20 purchase.product_supplierinfo

| FK | Tabla Destino | Existe | Notas |
|----|---------------|--------|-------|
| tenant_id | auth.tenants | ✅ | |
| company_id | core.companies | ❌ | ⚠️ Opcional |
| partner_id | core.partners | ❌ | ⚠️ Opcional |
| product_id | inventory.products | ❌ | ⚠️ Opcional |
| currency_id | core.currencies | ❌ | ⚠️ Opcional |

**Acción:** FKs opcionales.

---

## 5. Orden de Ejecución de Scripts

### 5.1 Orden Correcto para Nuevas Tablas

```
FASE A: ENUMs (sin dependencias)
├── financial.payment_method_type
├── financial.reconcile_model_type
├── hr.expense_status
├── hr.resume_line_type
└── hr.payslip_status

FASE B: Tablas Catálogo (sin dependencias)
├── financial.incoterms
└── inventory.removal_strategies

FASE C: Tablas Financial
├── financial.payment_term_lines
├── financial.payment_methods
├── financial.reconcile_models
└── financial.reconcile_model_lines

FASE D: Tablas Inventory
├── inventory.package_types
├── inventory.packages
├── inventory.storage_categories
└── inventory.putaway_rules

FASE E: Tablas Purchase
└── purchase.product_supplierinfo

FASE F: Tablas HR (orden de dependencia)
├── 1. hr.work_locations
├── 2. hr.skill_types
├── 3. hr.skills
├── 4. hr.skill_levels
├── 5. hr.employee_skills
├── 6. hr.expense_sheets
├── 7. hr.expenses
├── 8. hr.employee_resume_lines
├── 9. hr.payslip_structures
├── 10. hr.payslips
└── 11. hr.payslip_lines

FASE G: Extensión Construcción
├── 1. construction.ubicaciones_obra (requiere hr.work_locations)
└── 2. construction.avance_programado

FASE H: Tablas Projects (adaptadas)
├── projects.collaborators (adaptado a fraccionamientos)
└── projects.ratings

FASE I: Campos adicionales
├── ALTER TABLE financial.journal_entries
├── ALTER TABLE financial.payments
├── ALTER TABLE inventory.products
├── ALTER TABLE purchase.orders
├── ALTER TABLE construction.fraccionamientos
└── ALTER TABLE hr.employees

FASE J: Funciones y Triggers
├── construction.update_fraccionamiento_avance()
├── construction.generate_avance_snapshot()
└── purchase.action_create_stock_moves()

FASE K: Seed Data
├── Incoterms (11 registros)
├── Removal strategies (4 registros)
├── Skill types construcción (9 registros)
├── Skill levels (36 registros)
├── Skills específicos (~25 registros)
├── Storage categories (5 registros)
├── Package types (6 registros)
└── Payment methods (7 registros)
```

---

## 6. Riesgos Identificados

### 6.1 Riesgos Altos

| # | Riesgo | Impacto | Mitigación |
|---|--------|---------|------------|
| R1 | FK a tablas Core inexistentes | Alto | Usar FKs opcionales (sin constraint) |
| R2 | ENUMs duplicados con Core | Alto | Verificar antes de crear, usar IF NOT EXISTS |
| R3 | Tabla proyectos no existe | Alto | Adaptar a fraccionamientos |

### 6.2 Riesgos Medios

| # | Riesgo | Impacto | Mitigación |
|---|--------|---------|------------|
| R4 | Estructura hr.employees diferente | Medio | Usar ALTER con IF NOT EXISTS |
| R5 | Trigger en tabla inexistente | Medio | Usar DO $$ con verificación |
| R6 | Conflicto de políticas RLS | Medio | DROP POLICY IF EXISTS antes de CREATE |

### 6.3 Riesgos Bajos

| # | Riesgo | Impacto | Mitigación |
|---|--------|---------|------------|
| R7 | Seed data duplicado | Bajo | ON CONFLICT DO NOTHING |
| R8 | Índices duplicados | Bajo | CREATE INDEX IF NOT EXISTS |

---

## 7. Adaptaciones Requeridas al Plan

### 7.1 Cambios Críticos

| # | Elemento Original | Cambio Requerido |
|---|-------------------|------------------|
| 1 | `proyecto_id` FK | Cambiar a `fraccionamiento_id` |
| 2 | `construction.proyectos` | Usar `construction.fraccionamientos` |
| 3 | `construction.partidas` | Adaptar para `presupuesto_partidas` o `avances_obra` |
| 4 | Trigger conteo partidas | Adaptar para contar avances_obra por fraccionamiento |

### 7.2 Cambios en Tablas

**avance_programado:**
```sql
-- Antes:
proyecto_id UUID REFERENCES construction.proyectos(id)

-- Después:
fraccionamiento_id UUID REFERENCES construction.fraccionamientos(id)
```

**collaborators (adaptar):**
```sql
-- Crear versión específica para construcción
CREATE TABLE IF NOT EXISTS construction.colaboradores_obra (
  id UUID PRIMARY KEY,
  tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
  fraccionamiento_id UUID NOT NULL REFERENCES construction.fraccionamientos(id),
  partner_id UUID,  -- FK opcional a core.partners
  user_id UUID REFERENCES auth.users(id),
  rol VARCHAR(50),
  ...
);
```

### 7.3 Cambios en Funciones

**Trigger adaptado:**
```sql
-- En lugar de contar partidas, contar avances_obra
CREATE OR REPLACE FUNCTION construction.update_fraccionamiento_avance()
RETURNS TRIGGER AS $$
BEGIN
  -- Actualizar conteos en fraccionamiento basado en avances_obra
  UPDATE construction.fraccionamientos
  SET avance_count = (
    SELECT COUNT(*) FROM construction.avances_obra
    WHERE fraccionamiento_id = NEW.fraccionamiento_id
  )
  WHERE id = NEW.fraccionamiento_id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;
```

---

## 8. Matriz de Dependencias Final

### 8.1 Dependencias Externas (ERP-Core)

| Tabla Nueva | Requiere de Core | Estrategia |
|-------------|------------------|------------|
| payment_term_lines | financial.payment_terms | FK opcional |
| reconcile_models | core.companies | FK opcional |
| reconcile_model_lines | financial.accounts | FK opcional |
| collaborators | core.partners | FK opcional |
| expense_sheets | core.companies, currencies | FK opcional |
| expenses | inventory.products, currencies | FK opcional |
| payslips | hr.contracts | FK opcional |
| product_supplierinfo | core.partners, inventory.products | FK opcional |
| putaway_rules | inventory.locations, products | FK opcional |
| packages | inventory.locations | FK opcional |

### 8.2 Dependencias Internas (Orden)

```
1. ENUMs
2. Tablas catálogo (incoterms, removal_strategies)
3. financial.payment_methods, reconcile_models
4. financial.reconcile_model_lines (depende de reconcile_models)
5. financial.payment_term_lines
6. inventory.* (package_types → packages, storage_categories → putaway_rules)
7. hr.work_locations
8. construction.ubicaciones_obra (depende de work_locations)
9. hr.skill_types → hr.skills, hr.skill_levels
10. hr.employee_skills (depende de skills, levels)
11. hr.expense_sheets → hr.expenses
12. hr.employee_resume_lines
13. hr.payslip_structures → hr.payslips → hr.payslip_lines
14. purchase.product_supplierinfo
15. construction.avance_programado
16. construction.colaboradores_obra
17. projects.ratings
18. Campos adicionales (ALTERs)
19. Funciones y triggers
20. Seed data
```

---

## 9. Checklist de Validación Pre-Ejecución

- [ ] Verificar que auth.tenants existe
- [ ] Verificar que auth.users existe
- [ ] Verificar que construction.fraccionamientos existe
- [ ] Verificar que hr.employees existe
- [ ] Verificar estructura actual de hr.employees (campos existentes)
- [ ] Verificar si ENUMs ya existen en ERP-Core
- [ ] Confirmar que no hay conflictos de nombres de tablas
- [ ] Verificar permisos de creación de schemas

---

## 10. Resumen Ejecutivo

### 10.1 Hallazgos Principales

1. **No existe `construction.proyectos`** - Se usa `construction.fraccionamientos`
2. **No existe `construction.partidas`** como tabla independiente
3. **Múltiples FKs opcionales** a tablas de ERP-Core
4. **ENUMs pueden existir** en ERP-Core, requiere verificación

### 10.2 Decisiones de Diseño

1. Usar FKs sin REFERENCES para tablas opcionales de Core
2. Adaptar `proyecto_id` → `fraccionamiento_id` en todo el plan
3. Crear tabla `colaboradores_obra` en lugar de usar `projects.collaborators`
4. Usar IF NOT EXISTS en todos los CREATE

### 10.3 Impacto en FASE-3

El plan FASE-3 requiere actualización en:
- Todas las referencias a `proyecto_id`
- Todas las referencias a `construction.proyectos`
- Trigger de conteo de partidas
- Función de snapshot de avance

---

**Estado:** FASE 5 COMPLETADA
**Siguiente:** FASE 6 - Refinamiento del Plan
**Fecha:** 2026-01-04
