- Add CONTEXT-MAP.yml and ENVIRONMENT-INVENTORY.yml - Add propagacion-fase8 directory - Update project dependencies and context 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
566 lines
19 KiB
Markdown
566 lines
19 KiB
Markdown
# Architecture
|
|
|
|
## Overview
|
|
|
|
**ERP Suite** es una suite empresarial multi-vertical diseñada para SaaS simple autocontratado y proyectos integrales personalizados. La arquitectura maximiza la reutilización de código mediante un **core genérico** (60-70% compartido) que es extendido por **verticales especializadas** según el giro de negocio.
|
|
|
|
**Diseño basado en Odoo:** La arquitectura sigue los patrones de diseño de Odoo ERP, adaptados para Node.js/React.
|
|
|
|
## Tech Stack
|
|
|
|
- **Backend:** Node.js 20+ + Express.js 4.18+ + TypeScript 5.3+
|
|
- **Frontend Web:** React 18.3+ + Vite 5.4+ + TypeScript 5.6+ + Tailwind CSS
|
|
- **Frontend Mobile:** React Native (future)
|
|
- **Database:** PostgreSQL 15+ con RLS (Row-Level Security)
|
|
- **State Management:** Zustand 5.0
|
|
- **Validation:** Zod 3.22+
|
|
- **Auth:** JWT + bcryptjs
|
|
- **ORM:** pg (raw queries, no ORM pesado)
|
|
|
|
## Module Structure
|
|
|
|
### Project-Level Organization (Autocontenido)
|
|
|
|
```
|
|
erp-suite/
|
|
├── apps/
|
|
│ ├── erp-core/ # ERP Base (60-70% compartido)
|
|
│ │ ├── backend/ # Node.js + Express + TypeScript
|
|
│ │ │ └── src/
|
|
│ │ │ ├── modules/ # 14 módulos core
|
|
│ │ │ │ ├── auth/ # JWT, bcrypt, refresh tokens
|
|
│ │ │ │ ├── users/ # CRUD usuarios
|
|
│ │ │ │ ├── companies/ # Multi-company management
|
|
│ │ │ │ ├── core/ # Catálogos (monedas, países, UoM)
|
|
│ │ │ │ ├── partners/ # Clientes/proveedores
|
|
│ │ │ │ ├── inventory/ # Productos, almacenes, stock
|
|
│ │ │ │ ├── financial/ # Contabilidad
|
|
│ │ │ │ ├── purchases/ # Órdenes de compra
|
|
│ │ │ │ ├── sales/ # Cotizaciones, pedidos
|
|
│ │ │ │ ├── projects/ # Proyectos, tareas, timesheets
|
|
│ │ │ │ ├── crm/ # Leads, oportunidades
|
|
│ │ │ │ ├── hr/ # Nómina básica
|
|
│ │ │ │ └── system/ # Mensajes, notificaciones
|
|
│ │ │ ├── shared/ # Código compartido
|
|
│ │ │ │ ├── services/ # BaseService genérico
|
|
│ │ │ │ ├── middleware/ # Auth, error handling
|
|
│ │ │ │ ├── utils/ # Helpers
|
|
│ │ │ │ └── types/ # TypeScript types
|
|
│ │ │ ├── config/ # Configuration
|
|
│ │ │ └── routes/ # API routes
|
|
│ │ │
|
|
│ │ ├── frontend/ # React + Vite + Tailwind
|
|
│ │ │ └── src/
|
|
│ │ │ ├── modules/ # Feature modules
|
|
│ │ │ ├── shared/ # Shared components
|
|
│ │ │ └── layouts/ # App layouts
|
|
│ │ │
|
|
│ │ ├── database/ # PostgreSQL
|
|
│ │ │ ├── ddl/ # Schema definitions
|
|
│ │ │ │ └── schemas/ # 12 schemas, 144 tables
|
|
│ │ │ ├── migrations/ # Database migrations
|
|
│ │ │ └── seeds/ # Test data
|
|
│ │ │
|
|
│ │ ├── docs/ # Documentación PROPIA del core
|
|
│ │ └── orchestration/ # Sistema de agentes PROPIO
|
|
│ │
|
|
│ ├── verticales/
|
|
│ │ ├── construccion/ # Vertical INFONAVIT (35%)
|
|
│ │ │ ├── backend/ # Extensiones backend
|
|
│ │ │ │ └── src/
|
|
│ │ │ │ ├── modules/ # 15 módulos específicos
|
|
│ │ │ │ │ ├── projects/ # Override core projects
|
|
│ │ │ │ │ ├── budgets/ # Presupuestos obra
|
|
│ │ │ │ │ ├── construction/ # Control de obra
|
|
│ │ │ │ │ ├── quality/ # Calidad y postventa
|
|
│ │ │ │ │ ├── infonavit/ # Integración INFONAVIT
|
|
│ │ │ │ │ └── ...
|
|
│ │ │ │ └── shared/ # Extensiones compartidas
|
|
│ │ │ │
|
|
│ │ │ ├── frontend/ # UI específica construcción
|
|
│ │ │ ├── database/ # Schemas adicionales
|
|
│ │ │ │ └── ddl/
|
|
│ │ │ │ └── schemas/ # 7 schemas verticales
|
|
│ │ │ ├── docs/ # 403 docs (5.9 MB)
|
|
│ │ │ └── orchestration/ # Sistema de agentes PROPIO
|
|
│ │ │
|
|
│ │ ├── vidrio-templado/ # Vertical (0%)
|
|
│ │ │ ├── docs/
|
|
│ │ │ └── orchestration/
|
|
│ │ │
|
|
│ │ ├── mecanicas-diesel/ # Vertical (30%)
|
|
│ │ │ ├── docs/
|
|
│ │ │ └── orchestration/
|
|
│ │ │
|
|
│ │ ├── retail/ # Vertical POS
|
|
│ │ └── clinicas/ # Vertical Clínicas
|
|
│ │
|
|
│ ├── saas/ # Capa SaaS (billing, multi-tenant)
|
|
│ │ ├── onboarding/ # Onboarding de tenants
|
|
│ │ ├── admin/ # Admin panel SaaS
|
|
│ │ ├── billing/ # Facturación SaaS
|
|
│ │ └── portal/ # Portal cliente
|
|
│ │
|
|
│ └── shared-libs/ # Librerías compartidas
|
|
│ └── core/ # Utilidades cross-project
|
|
│
|
|
├── docs/ # Documentación GENERAL del suite
|
|
└── orchestration/ # Orquestación GENERAL del suite
|
|
```
|
|
|
|
## Database Schemas
|
|
|
|
### ERP Core (12 schemas, 144 tables)
|
|
|
|
| Schema | Purpose | Tables | Key Entities |
|
|
|--------|---------|--------|--------------|
|
|
| **auth** | Autenticación, usuarios, roles | 10 | users, roles, permissions, sessions |
|
|
| **core** | Partners, catálogos | 12 | partners, currencies, countries, uom |
|
|
| **analytics** | Contabilidad analítica | 7 | analytic_accounts, cost_centers |
|
|
| **financial** | Facturas, pagos | 15 | invoices, payments, journals, accounts |
|
|
| **products** | Productos, categorías | 8 | products, categories, pricelists |
|
|
| **inventory** | Almacenes, stock | 14 | warehouses, locations, stock_moves |
|
|
| **sales** | Ventas | 10 | quotations, sales_orders, deliveries |
|
|
| **purchases** | Compras | 12 | purchase_orders, receptions |
|
|
| **projects** | Proyectos, tareas | 18 | projects, tasks, timesheets |
|
|
| **hr** | Recursos humanos | 12 | employees, contracts, payroll |
|
|
| **crm** | CRM | 10 | leads, opportunities, campaigns |
|
|
| **system** | Sistema | 16 | messages, notifications, settings |
|
|
|
|
### Vertical Construcción (7 schemas adicionales, 60+ tables)
|
|
|
|
| Schema | Purpose | Tables |
|
|
|--------|---------|--------|
|
|
| **project_management** | Proyectos, desarrollos, fases | 15 |
|
|
| **financial_management** | Presupuestos, estimaciones | 12 |
|
|
| **construction_management** | Avances, recursos, materiales | 10 |
|
|
| **quality_management** | Inspecciones, pruebas | 8 |
|
|
| **infonavit_management** | Integración INFONAVIT | 7 |
|
|
| **purchasing_management** | Compras específicas | 6 |
|
|
| **crm_management** | CRM Derechohabientes | 5 |
|
|
|
|
## Data Flow Architecture
|
|
|
|
```
|
|
┌──────────────┐
|
|
│ Frontend │ (React SPA)
|
|
│ (Browser) │
|
|
└──────┬───────┘
|
|
│ HTTP
|
|
▼
|
|
┌─────────────────────────────────────────┐
|
|
│ Backend API (Express.js) │
|
|
│ ┌─────────────────────────────────┐ │
|
|
│ │ Routes (REST Endpoints) │ │
|
|
│ └────────┬────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────┐ │
|
|
│ │ Controllers │ │
|
|
│ └────────┬────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────┐ │
|
|
│ │ Services (Business Logic) │ │
|
|
│ │ - BaseService<T> │ │
|
|
│ │ - Multi-tenancy enforcement │ │
|
|
│ └────────┬────────────────────────┘ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────┐ │
|
|
│ │ Database (pg driver) │ │
|
|
│ │ - Raw SQL queries │ │
|
|
│ │ - Parameterized │ │
|
|
│ └─────────────────────────────────┘ │
|
|
└───────────┼──────────────────────────────┘
|
|
▼
|
|
┌─────────────────┐
|
|
│ PostgreSQL │
|
|
│ (RLS enabled) │
|
|
│ tenant_id │
|
|
└─────────────────┘
|
|
```
|
|
|
|
### Multi-Tenancy Flow
|
|
|
|
```
|
|
1. User login → JWT with tenant_id
|
|
2. Request to API with JWT
|
|
3. Middleware extracts tenant_id
|
|
4. SET LOCAL app.current_tenant_id = 'tenant-uuid'
|
|
5. RLS policies filter data automatically
|
|
6. Only tenant's data returned
|
|
```
|
|
|
|
## Key Design Decisions
|
|
|
|
### 1. BaseService Pattern (Elimina duplicación de código)
|
|
|
|
**Decision:** Implementar servicio genérico base que todos los módulos extienden.
|
|
|
|
**Rationale:**
|
|
- Elimina ~80% de código duplicado CRUD
|
|
- Multi-tenancy enforcement automático
|
|
- Paginación, filtrado, búsqueda consistente
|
|
- Soft-delete por defecto
|
|
- Transactions simplificadas
|
|
|
|
**Implementation:**
|
|
|
|
```typescript
|
|
// shared/services/base.service.ts
|
|
abstract class BaseService<T, CreateDto, UpdateDto> {
|
|
constructor(
|
|
protected tableName: string,
|
|
protected schema: string
|
|
) {}
|
|
|
|
async findAll(
|
|
tenantId: string,
|
|
filters?: Filters,
|
|
pagination?: Pagination
|
|
): Promise<PaginatedResult<T>> {
|
|
// Auto-adds tenant_id filter
|
|
// Supports: search, sort, pagination
|
|
// Returns: { data, total, page, limit }
|
|
}
|
|
|
|
async findById(id: string, tenantId: string): Promise<T | null> {}
|
|
|
|
async create(data: CreateDto, tenantId: string, userId: string): Promise<T> {}
|
|
|
|
async update(id: string, data: UpdateDto, tenantId: string, userId: string): Promise<T> {}
|
|
|
|
async softDelete(id: string, tenantId: string, userId: string): Promise<boolean> {}
|
|
|
|
async withTransaction<R>(fn: (client: PoolClient) => Promise<R>): Promise<R> {}
|
|
}
|
|
```
|
|
|
|
**Usage:**
|
|
|
|
```typescript
|
|
// modules/products/product.service.ts
|
|
class ProductService extends BaseService<Product, CreateProductDto, UpdateProductDto> {
|
|
constructor() {
|
|
super('products', 'products');
|
|
}
|
|
|
|
// Override only when needed
|
|
async findByBarcode(barcode: string, tenantId: string): Promise<Product | null> {
|
|
// Custom query
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Schema-Level Multi-Tenancy + RLS
|
|
|
|
**Decision:** Usar `tenant_id` en cada tabla + Row-Level Security de PostgreSQL.
|
|
|
|
**Rationale:**
|
|
- Aislamiento a nivel de base de datos (más seguro)
|
|
- RLS previene acceso cruzado incluso con bugs
|
|
- No requiere filtros manuales en cada query
|
|
- Compatible con herramientas de BI
|
|
|
|
**Implementation:**
|
|
|
|
```sql
|
|
-- Todas las tablas
|
|
CREATE TABLE products.products (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
|
|
name VARCHAR(255) NOT NULL,
|
|
-- ...
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- RLS Policy estándar
|
|
ALTER TABLE products.products ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY tenant_isolation ON products.products
|
|
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
|
|
```
|
|
|
|
**Backend:**
|
|
|
|
```typescript
|
|
// Middleware sets tenant context
|
|
app.use(async (req, res, next) => {
|
|
const tenantId = req.user.tenantId;
|
|
await pool.query(`SET LOCAL app.current_tenant_id = $1`, [tenantId]);
|
|
next();
|
|
});
|
|
```
|
|
|
|
### 3. Vertical Extension Pattern (Herencia de Módulos)
|
|
|
|
**Decision:** Las verticales extienden módulos del core sin modificarlos.
|
|
|
|
**Rationale:**
|
|
- Core permanece genérico y reutilizable
|
|
- Verticales no "rompen" el core
|
|
- Actualizaciones del core no afectan verticales
|
|
- Basado en patrón de Odoo ERP
|
|
|
|
**Pattern:**
|
|
|
|
```typescript
|
|
// Core: erp-core/backend/src/modules/projects/project.service.ts
|
|
class ProjectService extends BaseService<Project, CreateProjectDto, UpdateProjectDto> {
|
|
// Logic genérica
|
|
}
|
|
|
|
// Vertical: construccion/backend/src/modules/projects/construction-project.service.ts
|
|
class ConstructionProjectService extends ProjectService {
|
|
// Override methods
|
|
async create(data: CreateConstructionProjectDto, tenantId, userId) {
|
|
// Add construction-specific logic
|
|
const project = await super.create(data, tenantId, userId);
|
|
await this.createDevelopment(project.id, data.development);
|
|
return project;
|
|
}
|
|
|
|
// Add new methods
|
|
async createPhase(projectId: string, phase: PhaseDto) {}
|
|
async linkToINFONAVIT(projectId: string, infonavitData: any) {}
|
|
}
|
|
```
|
|
|
|
### 4. Raw SQL over Heavy ORM
|
|
|
|
**Decision:** Usar driver `pg` con queries SQL en lugar de ORM (TypeORM, Prisma).
|
|
|
|
**Rationale:**
|
|
- Mayor control sobre queries complejas
|
|
- Mejor performance (no overhead ORM)
|
|
- DDL mantenido manualmente = documentación viva
|
|
- Compatible con RLS (muchos ORMs tienen problemas)
|
|
- Evita migraciones automáticas peligrosas
|
|
|
|
**Trade-off:**
|
|
- Más código SQL manual
|
|
- No hay auto-migrations
|
|
- Type-safety requiere interfaces manuales
|
|
|
|
**Mitigación:**
|
|
- BaseService abstrae CRUD común
|
|
- TypeScript interfaces tipan resultados
|
|
- SQL formateado y versionado en DDL
|
|
|
|
### 5. Soft Delete por Defecto
|
|
|
|
**Decision:** Todas las tablas tienen `deleted_at` para soft delete.
|
|
|
|
**Rationale:**
|
|
- Cumplimiento regulatorio (auditoría)
|
|
- Recuperación de datos borrados
|
|
- Integridad referencial preservada
|
|
- Historial completo
|
|
|
|
**Implementation:**
|
|
|
|
```sql
|
|
ALTER TABLE products.products
|
|
ADD COLUMN deleted_at TIMESTAMPTZ;
|
|
|
|
-- BaseService auto-filtra deleted_at IS NULL
|
|
```
|
|
|
|
### 6. Pattern-Based on Odoo
|
|
|
|
**Decision:** Replicar patrones de diseño de Odoo ERP (módulos, herencia, vistas).
|
|
|
|
**Rationale:**
|
|
- Odoo es el ERP open-source más exitoso
|
|
- Patrones probados en miles de empresas
|
|
- Equipo familiarizado con Odoo
|
|
- Facilita migración futura de datos Odoo
|
|
|
|
**Patterns Adopted:**
|
|
- Modular architecture
|
|
- Inheritance (core → vertical)
|
|
- Catálogos (countries, currencies, UoM)
|
|
- Multi-company
|
|
- Wizard pattern for complex operations
|
|
|
|
Ver: `../../erp-core/orchestration/directivas/DIRECTIVA-PATRONES-ODOO.md`
|
|
|
|
## Dependencies
|
|
|
|
### Critical Dependencies
|
|
|
|
| Dependency | Purpose | Criticality |
|
|
|------------|---------|-------------|
|
|
| **PostgreSQL 15+** | Database with RLS | CRITICAL |
|
|
| **Node.js 20+** | Runtime | CRITICAL |
|
|
| **Express.js** | Web framework | CRITICAL |
|
|
| **React 18+** | Frontend | CRITICAL |
|
|
| **pg** | PostgreSQL driver | CRITICAL |
|
|
| **Zod** | Validation | HIGH |
|
|
| **Zustand** | State management | MEDIUM |
|
|
|
|
### Internal Dependencies
|
|
|
|
- **erp-core:** Base compartida para todas las verticales
|
|
- **Verticales:** Dependen de erp-core (herencia)
|
|
- **SaaS layer:** Depende de erp-core y verticales
|
|
|
|
## Security Considerations
|
|
|
|
- **Authentication:** JWT con refresh tokens
|
|
- **Authorization:** RBAC (Role-Based Access Control)
|
|
- **Multi-tenancy:** RLS garantiza aislamiento de datos
|
|
- **Password Hashing:** bcryptjs (10 rounds)
|
|
- **Input Validation:** Zod schemas
|
|
- **SQL Injection:** Parameterized queries (pg)
|
|
- **XSS Protection:** React auto-escape
|
|
- **CORS:** Configurado por entorno
|
|
|
|
Ver documentación completa: [MULTI-TENANCY.md](./MULTI-TENANCY.md)
|
|
|
|
## Performance Optimizations
|
|
|
|
### Database
|
|
- Indexes en columnas frecuentes (`tenant_id`, `created_at`, foreign keys)
|
|
- Partitioning en tablas grandes (future)
|
|
- Connection pooling (pg.Pool)
|
|
- EXPLAIN ANALYZE para optimización
|
|
|
|
### Backend
|
|
- Response caching (future: Redis)
|
|
- Pagination obligatoria en listas
|
|
- Lazy loading de relaciones
|
|
- Batch operations
|
|
|
|
### Frontend
|
|
- Code splitting (React.lazy)
|
|
- Virtual scrolling para listas largas
|
|
- Debouncing en búsquedas
|
|
- Optimistic UI updates
|
|
|
|
## Deployment Strategy
|
|
|
|
**Current:** Development environment
|
|
|
|
**Future Production:**
|
|
- Docker containers
|
|
- Kubernetes orchestration
|
|
- Multi-region for latency
|
|
- Database replicas (read/write split)
|
|
|
|
## Monitoring & Observability
|
|
|
|
**Planned:**
|
|
- Winston logging
|
|
- Error tracking (Sentry)
|
|
- Performance monitoring (Datadog)
|
|
- Database monitoring (pgAdmin, pg_stat_statements)
|
|
|
|
## Vertical Development Order
|
|
|
|
**Recomendado:**
|
|
|
|
1. **ERP Core** (base genérica) - 60% completado
|
|
2. **Construcción** (más avanzado) - 35% completado
|
|
3. **Vidrio Templado** - 0%
|
|
4. **Mecánicas Diesel** - 30%
|
|
5. **Retail** - 0%
|
|
6. **Clínicas** - 0%
|
|
|
|
## Module Breakdown (ERP Core)
|
|
|
|
### Auth Module
|
|
- JWT authentication
|
|
- Refresh tokens
|
|
- Password reset
|
|
- Email verification
|
|
- RBAC (roles, permissions)
|
|
|
|
### Users Module
|
|
- CRUD usuarios
|
|
- User profiles
|
|
- Preferences
|
|
- Activity tracking
|
|
|
|
### Companies Module
|
|
- Multi-company support
|
|
- Company settings
|
|
- Fiscal configuration
|
|
|
|
### Partners Module
|
|
- Clientes y proveedores
|
|
- Contactos
|
|
- Direcciones
|
|
- Categorías
|
|
|
|
### Inventory Module
|
|
- Productos
|
|
- Categorías
|
|
- Almacenes
|
|
- Movimientos de stock
|
|
- Valoración (FIFO, LIFO, Average)
|
|
|
|
### Financial Module
|
|
- Plan de cuentas
|
|
- Diarios contables
|
|
- Asientos contables
|
|
- Conciliación bancaria
|
|
- Reportes financieros
|
|
|
|
### Sales Module
|
|
- Cotizaciones
|
|
- Órdenes de venta
|
|
- Entregas
|
|
- Facturación
|
|
|
|
### Purchases Module
|
|
- Solicitudes de compra
|
|
- Órdenes de compra
|
|
- Recepciones
|
|
- Facturas de proveedor
|
|
|
|
### Projects Module
|
|
- Proyectos
|
|
- Tareas
|
|
- Timesheets
|
|
- Planificación
|
|
|
|
### HR Module
|
|
- Empleados
|
|
- Contratos
|
|
- Nómina básica
|
|
- Asistencias
|
|
|
|
### CRM Module
|
|
- Leads
|
|
- Oportunidades
|
|
- Campañas
|
|
- Pipeline
|
|
|
|
## Future Improvements
|
|
|
|
### Short-term
|
|
- [ ] Completar modules faltantes en erp-core
|
|
- [ ] Implementar tests unitarios
|
|
- [ ] Agregar Redis caching
|
|
- [ ] Mobile app (React Native)
|
|
|
|
### Medium-term
|
|
- [ ] Completar vertical Construcción
|
|
- [ ] Implementar vertical Vidrio Templado
|
|
- [ ] SaaS layer (billing, onboarding)
|
|
- [ ] Marketplace de módulos
|
|
|
|
### Long-term
|
|
- [ ] Multi-currency completo
|
|
- [ ] Integración con pasarelas de pago
|
|
- [ ] BI/Analytics integrado
|
|
- [ ] AI-powered features
|
|
- [ ] White-label solution
|
|
|
|
## References
|
|
|
|
- [Multi-Tenancy Guide](./MULTI-TENANCY.md)
|
|
- [Vertical Development Guide](./VERTICAL-GUIDE.md)
|
|
- [Odoo Patterns](../../erp-core/orchestration/directivas/DIRECTIVA-PATRONES-ODOO.md)
|
|
- [Database Schema](../apps/erp-core/database/ddl/)
|
|
- [Directivas ERP](../apps/erp-core/orchestration/directivas/)
|