# GRAFO DE DEPENDENCIAS ENTRE SCHEMAS Y TABLAS

**Proyecto:** ERP Generic
**Fecha:** 2025-11-24
**Versión:** 1.0.0

---

## 1. Jerarquía de Schemas (Orden de Creación)

```
Nivel 0 (Base - Sin dependencias):
├── prerequisites (extensions, utility functions, composite types)

Nivel 1 (Foundations):
├── auth (tenants, companies, users, roles, permissions, sessions)
├── core (countries, currencies, uom_categories, uom)

Nivel 2 (Dependent on auth + core):
├── core.partners (FK → auth.tenants, auth.companies, auth.users, core.currencies)
├── core.addresses (FK → core.partners, core.countries)
├── core.product_categories (FK → auth.tenants)
├── financial.account_types (Sin FKs externas)

Nivel 3 (Dependent on Nivel 2):
├── analytics (FK → auth, core.partners, financial)
├── financial (FK → auth, core, analytics)
├── inventory (FK → auth, core)

Nivel 4 (Dependent on Nivel 3):
├── purchase (FK → auth, core, financial, inventory, analytics)
├── sales (FK → auth, core, financial, inventory, analytics)

Nivel 5 (Dependent on Nivel 4):
├── projects (FK → auth, core, analytics, inventory)

Nivel 6 (Cross-cutting):
├── system (FK → auth, core, todos los anteriores)
```

---

## 2. Diagrama de Dependencias por Schema

### Auth Schema (Nivel 1)
```
auth.tenants ─────────────────────────────────────────────────────┐
    │                                                              │
    ├── auth.companies (tenant_id, parent_company_id)             │
    │       └── FK: core.currencies(id)                            │
    │       └── FK: core.partners(id) [partner_id]                 │
    │                                                              │
    ├── auth.users (tenant_id)                                     │
    │                                                              │
    ├── auth.roles (tenant_id)                                     │
    │                                                              │
    └── auth.permissions (no tenant_id - global)                   │
                                                                   │
    auth.user_roles ──── FK: auth.users(id), auth.roles(id)       │
    auth.role_permissions ── FK: auth.roles(id), auth.permissions │
    auth.sessions ──── FK: auth.users(id)                          │
    auth.user_companies ── FK: auth.users(id), auth.companies(id) │
    auth.password_resets ── FK: auth.users(id)                     │
```

### Core Schema (Nivel 1-2)
```
Catálogos Base (Sin FKs externas):
├── core.countries
├── core.currencies
├── core.uom_categories
└── core.uom (FK → uom_categories)

Entidades Multi-tenant:
├── core.partners ─── FK: auth.tenants, auth.companies, auth.users,
│                     core.currencies, core.partners(parent)
│
├── core.addresses ─── FK: core.partners, core.countries
│
├── core.product_categories ─── FK: auth.tenants, self(parent_id)
│
├── core.exchange_rates ─── FK: core.currencies (from/to)
│
├── core.sequences ─── FK: auth.tenants, auth.companies
│
├── core.tags ─── FK: auth.tenants
│
├── core.attachments ─── FK: auth.tenants (polimórfico: model, record_id)
│
└── core.notes ─── FK: auth.tenants (polimórfico: model, record_id)
```

### Analytics Schema (Nivel 3)
```
analytics.analytic_plans ─── FK: auth.tenants, auth.companies
    │
    └── analytics.analytic_accounts ─── FK: auth.tenants, auth.companies,
            │                            analytics.analytic_plans,
            │                            self(parent_id), core.partners
            │
            ├── analytics.cost_centers ─── FK: analytics.analytic_accounts,
            │                              auth.users(manager)
            │
            └── analytics.analytic_lines ─── FK: auth.tenants, auth.companies,
                    │                         analytics.analytic_accounts,
                    │                         core.partners, core.currencies,
                    │                         inventory.products
                    │
                    └── analytics.analytic_line_tags ─── FK: analytic_lines,
                                                          analytic_tags

analytics.analytic_tags ─── FK: auth.tenants

analytics.analytic_distributions ─── FK: analytics.analytic_accounts
                                      (polimórfico: source_model, source_id)
```

### Financial Schema (Nivel 3)
```
financial.account_types (catálogo base)
    │
    └── financial.accounts ─── FK: auth.tenants, auth.companies,
            │                   financial.account_types, self(parent),
            │                   core.currencies
            │
            └── financial.journals ─── FK: auth.tenants, auth.companies,
                    │                   financial.accounts, core.sequences,
                    │                   core.currencies
                    │
                    └── financial.journal_entries ─── FK: auth.tenants,
                            │                          auth.companies,
                            │                          financial.journals
                            │
                            └── financial.journal_entry_lines ─── FK: journal_entries,
                                                                   financial.accounts,
                                                                   core.partners,
                                                                   core.currencies,
                                                                   analytics.analytic_accounts

financial.fiscal_years ─── FK: auth.tenants, auth.companies
    │
    └── financial.fiscal_periods ─── FK: auth.tenants, financial.fiscal_years

financial.taxes ─── FK: auth.tenants, auth.companies, financial.accounts

financial.payment_terms ─── FK: auth.tenants, auth.companies

financial.invoices ─── FK: auth.tenants, auth.companies, core.partners,
    │                   core.currencies, financial.payment_terms,
    │                   financial.journals, financial.journal_entries
    │
    └── financial.invoice_lines ─── FK: financial.invoices, core.uom,
                                     financial.accounts, analytics.analytic_accounts

financial.payments ─── FK: auth.tenants, auth.companies, core.partners,
    │                   core.currencies, financial.journals,
    │                   financial.journal_entries
    │
    └── financial.payment_invoice ─── FK: financial.payments, financial.invoices

financial.bank_accounts ─── FK: auth.tenants, auth.companies, core.partners,
    │                        core.currencies, financial.journals
    │
    └── financial.reconciliations ─── FK: auth.tenants, auth.companies,
                                       financial.bank_accounts
```

### Inventory Schema (Nivel 3)
```
inventory.products ─── FK: auth.tenants, core.product_categories, core.uom
    │
    ├── inventory.product_variants ─── FK: inventory.products
    │
    └── inventory.lots ─── FK: auth.tenants, inventory.products

inventory.warehouses ─── FK: auth.tenants, auth.companies, core.addresses
    │
    └── inventory.locations ─── FK: auth.tenants, inventory.warehouses,
            │                     self(parent_id)
            │
            └── inventory.stock_quants ─── FK: inventory.products,
                                            inventory.locations,
                                            inventory.lots

inventory.pickings ─── FK: auth.tenants, auth.companies, inventory.locations(x2),
    │                   core.partners
    │
    └── inventory.stock_moves ─── FK: auth.tenants, inventory.products,
                                   core.uom, inventory.locations(x2),
                                   inventory.lots, inventory.pickings,
                                   analytics.analytic_accounts

inventory.inventory_adjustments ─── FK: auth.tenants, auth.companies,
    │                                 inventory.locations
    │
    └── inventory.inventory_adjustment_lines ─── FK: adjustments,
                                                  inventory.products,
                                                  inventory.locations,
                                                  inventory.lots
```

### Purchase Schema (Nivel 4)
```
purchase.purchase_orders ─── FK: auth.tenants, auth.companies, core.partners,
    │                         core.currencies, financial.payment_terms,
    │                         inventory.pickings, financial.invoices
    │
    └── purchase.purchase_order_lines ─── FK: purchase_orders, inventory.products,
                                           core.uom, analytics.analytic_accounts

purchase.rfqs ─── FK: auth.tenants, auth.companies
    │
    └── purchase.rfq_lines ─── FK: rfqs, inventory.products, core.uom

purchase.vendor_pricelists ─── FK: auth.tenants, core.partners,
                                inventory.products, core.currencies

purchase.purchase_agreements ─── FK: auth.tenants, auth.companies, core.partners,
    │                             core.currencies
    │
    └── purchase.purchase_agreement_lines ─── FK: agreements, inventory.products

purchase.vendor_evaluations ─── FK: auth.tenants, auth.companies, core.partners
```

### Sales Schema (Nivel 4)
```
sales.pricelists ─── FK: auth.tenants, auth.companies, core.currencies
    │
    └── sales.pricelist_items ─── FK: pricelists, inventory.products,
                                   core.product_categories

sales.sales_teams ─── FK: auth.tenants, auth.companies, auth.users(leader)
    │
    └── sales.sales_team_members ─── FK: sales_teams, auth.users

sales.customer_groups ─── FK: auth.tenants
    │
    └── sales.customer_group_members ─── FK: customer_groups, core.partners

sales.quotations ─── FK: auth.tenants, auth.companies, core.partners,
    │                 core.currencies, sales.pricelists, auth.users,
    │                 sales.sales_teams, sales.sales_orders
    │
    └── sales.quotation_lines ─── FK: quotations, inventory.products, core.uom

sales.sales_orders ─── FK: auth.tenants, auth.companies, core.partners,
    │                   core.currencies, sales.pricelists, financial.payment_terms,
    │                   auth.users, sales.sales_teams, inventory.pickings
    │
    └── sales.sales_order_lines ─── FK: sales_orders, inventory.products,
                                     core.uom, analytics.analytic_accounts
```

### Projects Schema (Nivel 5)
```
projects.projects ─── FK: auth.tenants, auth.companies, auth.users(manager),
    │                  core.partners, analytics.analytic_accounts
    │
    ├── projects.project_stages ─── FK: auth.tenants, projects
    │
    ├── projects.milestones ─── FK: auth.tenants, projects
    │
    └── projects.tasks ─── FK: auth.tenants, projects, project_stages,
            │               auth.users(assigned), core.partners, self(parent),
            │               milestones
            │
            ├── projects.task_dependencies ─── FK: tasks(x2)
            │
            ├── projects.task_tag_assignments ─── FK: tasks, task_tags
            │
            └── projects.task_checklists ─── FK: tasks

projects.task_tags ─── FK: auth.tenants

projects.timesheets ─── FK: auth.tenants, auth.companies, projects.tasks,
                         projects.projects, auth.users,
                         analytics.analytic_accounts, analytics.analytic_lines

projects.project_templates ─── FK: auth.tenants
```

### System Schema (Nivel 6 - Cross-cutting)
```
system.messages ─── FK: auth.tenants, auth.users, self(parent)
                    (polimórfico: model, record_id)

system.message_followers ─── FK: core.partners, auth.users
                              (polimórfico: model, record_id)

system.notifications ─── FK: auth.tenants, auth.users
                          (polimórfico: model, record_id)

system.activities ─── FK: auth.tenants, auth.users(assigned_to, assigned_by)
                       (polimórfico: model, record_id)

system.message_templates ─── FK: auth.tenants

system.email_queue ─── FK: auth.tenants

system.logs ─── FK: auth.tenants, auth.users
                 (polimórfico: model, record_id)

system.reports ─── FK: auth.tenants
    │
    └── system.report_executions ─── FK: auth.tenants, reports

system.dashboards ─── FK: auth.tenants, auth.users
    │
    └── system.dashboard_widgets ─── FK: dashboards

system.field_tracking_config ─── (sin FKs - configuración global)

system.change_log ─── FK: auth.tenants, auth.users
                       (polimórfico: table_schema, table_name, record_id)
```

---

## 3. Orden de Ejecución DDL (Resuelve Dependencias)

```sql
-- FASE 1: Prerequisites (sin dependencias)
\i 00-prerequisites.sql

-- FASE 2: Schema auth (fundacional)
\i 01-auth.sql       -- Solo crea: tenants, roles, permissions, users básico

-- FASE 3: Schema core catálogos (sin FKs a auth.companies)
\i 02-core.sql       -- countries, currencies, uom_categories, uom

-- FASE 4: Schema auth completo (ahora puede referenciar core.currencies)
-- Ya incluido en 01-auth.sql con DEFERRED constraints

-- FASE 5: Core entidades (partners, addresses, etc.)
-- Ya incluido en 02-core.sql

-- FASE 6: Analytics (depende de auth + core)
\i 03-analytics.sql

-- FASE 7: Financial (depende de auth + core + analytics)
\i 04-financial.sql

-- FASE 8: Inventory (depende de auth + core)
\i 05-inventory.sql

-- FASE 9: Purchase (depende de todos los anteriores)
\i 06-purchase.sql

-- FASE 10: Sales (depende de todos los anteriores)
\i 07-sales.sql

-- FASE 11: Projects (depende de auth + core + analytics)
\i 08-projects.sql

-- FASE 12: System (cross-cutting, puede referenciar cualquier tabla)
\i 09-system.sql
```

---

## 4. Dependencias Circulares Identificadas

### Ciclo 1: auth.companies ↔ core.partners
```
auth.companies.partner_id → core.partners(id)
core.partners.company_id → auth.companies(id)
```
**Resolución:** FKs creadas con `DEFERRABLE INITIALLY DEFERRED`

### Ciclo 2: financial.invoices ↔ financial.journal_entries
```
financial.invoices.journal_entry_id → financial.journal_entries(id)
financial.journal_entry_lines.invoice_id → financial.invoices(id) [implícito]
```
**Resolución:** journal_entry_id es nullable, se asigna después de crear el asiento

### Ciclo 3: projects.tasks ↔ projects.milestones
```
projects.tasks.milestone_id → projects.milestones(id)
projects.milestones contiene tasks completadas
```
**Resolución:** milestone_id es nullable

---

## 5. Resumen de Dependencias

| Schema | Depende de | Depende de él |
|--------|------------|---------------|
| auth | - | core, analytics, financial, inventory, purchase, sales, projects, system |
| core | auth | analytics, financial, inventory, purchase, sales, projects, system |
| analytics | auth, core | financial, purchase, sales, projects |
| financial | auth, core, analytics | purchase, sales |
| inventory | auth, core | purchase, sales, projects |
| purchase | auth, core, financial, inventory, analytics | - |
| sales | auth, core, financial, inventory, analytics | - |
| projects | auth, core, analytics | - |
| system | auth, core | - |

---

## 6. Validación de Integridad

### Checks Realizados:
- [x] No hay dependencias circulares sin resolver
- [x] Todas las FKs tienen índices correspondientes
- [x] RLS policies aplicadas a todas las tablas multi-tenant
- [x] Triggers updated_at en todas las tablas con updated_at
- [x] Soft delete (deleted_at) consistente donde aplica

### Recomendaciones:
1. Ejecutar DDL en orden especificado
2. Usar `SET CONSTRAINTS ALL DEFERRED` para cargas masivas
3. Validar FKs después de migración: `SELECT * FROM pg_constraint WHERE NOT convalidated`

---

**Generado por:** Architecture-Analyst
**Fecha:** 2025-11-24
