- Rename _archivo to _archive (standard convention) - Move analisis/, planes/ to _archive/ - Archive extra root files - Update _MAP.md with standardized structure Standard: SIMCO-ESTANDAR-ORCHESTRATION v1.0.0 Level: PROVIDER (L1A) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
19 KiB
FASE 5: Plan Refinado de Ejecucion
Fecha: 2026-01-10 Estado: APROBADO PARA EJECUCION Objetivo: Plan consolidado y optimizado para ejecucion
1. Resumen del Plan Refinado
1.1 Metricas de Ejecucion
| Metrica | Valor |
|---|---|
| Total de archivos a modificar | 12 |
| Total de correcciones | 19 |
| Grupos de ejecucion | 6 |
| Tiempo estimado total | 3h 30min (optimizado) |
1.2 Archivos por Orden de Ejecucion
| Orden | Archivo | Correcciones Agrupadas |
|---|---|---|
| 1 | SAAS-008-audit-logs.md | CRIT-007, ALTO-006 |
| 2 | SAAS-009-feature-flags.md | CRIT-007 |
| 3 | SAAS-012-crud-base.md | CRIT-003 |
| 4 | SAAS-002-tenants.md | ALTO-003 |
| 5 | SAAS-006-ai-integration.md | ALTO-007 |
| 6 | SAAS-003-users.md | MEDIO-004 |
| 7 | SAAS-001-auth.md | CRIT-004, CRIT-005, ALTO-002, MEDIO-001, MEDIO-002 |
| 8 | SAAS-004-billing.md | CRIT-002, ALTO-001, ALTO-005, MEDIO-003 |
| 9 | SAAS-007-notifications.md | ALTO-004 |
| 10 | MASTER_INVENTORY.yml | CRIT-001, CRIT-006, MEDIO-005 |
| 11 | DATABASE_INVENTORY.yml | CRIT-001, MEDIO-005 |
| 12 | Otros (PROJECT-STATUS, _MAP, CONTEXT-MAP) | CRIT-001, CRIT-006 |
2. Instrucciones Detalladas por Archivo
EJECUCION-001: SAAS-008-audit-logs.md
Ubicacion: docs/01-modulos/SAAS-008-audit-logs.md
Cambios a realizar:
- Metadata - Cambiar estado:
# ANTES:
| Estado | Pendiente |
# DESPUES:
| Estado | Completado |
- Agregar nota sobre export (si existe endpoint documentado):
## Endpoints
### GET /audit/export
**Estado:** Pendiente de implementacion
**Descripcion:** Exportar logs en formato CSV o JSON
Validacion:
grep -E "Estado.*Completado" docs/01-modulos/SAAS-008-audit-logs.md
EJECUCION-002: SAAS-009-feature-flags.md
Ubicacion: docs/01-modulos/SAAS-009-feature-flags.md
Cambios a realizar:
- Metadata - Cambiar estado:
# ANTES:
| Estado | Pendiente |
# DESPUES:
| Estado | Completado |
Validacion:
grep -E "Estado.*Completado" docs/01-modulos/SAAS-009-feature-flags.md
EJECUCION-003: SAAS-012-crud-base.md
Ubicacion: docs/01-modulos/SAAS-012-crud-base.md
Accion: Reescribir completamente
Nuevo contenido:
# SAAS-012: Patrones Base CRUD
## Metadata
| Campo | Valor |
|-------|-------|
| Codigo | SAAS-012 |
| Modulo | crud-base |
| Prioridad | P2 |
| Estado | Documentacion |
| Tipo | Guia de Patrones |
| Ultima Actualizacion | 2026-01-10 |
---
## Descripcion
Este documento describe los patrones CRUD utilizados en el proyecto template-saas.
Actualmente cada modulo implementa su propia logica CRUD de forma independiente,
siguiendo convenciones comunes.
---
## Patron Arquitectonico Actual
### Estructura por Modulo
Cada modulo backend contiene:
modules/[nombre]/ ├── [nombre].controller.ts # Endpoints REST ├── [nombre].module.ts # Configuracion NestJS ├── [nombre].service.ts # Logica de negocio ├── dto/ │ ├── create-[nombre].dto.ts │ ├── update-[nombre].dto.ts │ └── [nombre]-response.dto.ts ├── entities/ │ └── [nombre].entity.ts # Entidad TypeORM └── tests/ └── [nombre].service.spec.ts
### Campos Base Comunes
Todas las entidades incluyen estos campos base:
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| id | UUID | Primary key, auto-generado |
| tenant_id | UUID | Foreign key a tenants (RLS) |
| created_at | TIMESTAMP | Fecha de creacion |
| updated_at | TIMESTAMP | Fecha ultima modificacion |
| deleted_at | TIMESTAMP | Soft delete (nullable) |
| created_by | UUID | Usuario que creo (opcional) |
| updated_by | UUID | Usuario que modifico (opcional) |
### Patron de Paginacion
Todos los endpoints de listado soportan:
```typescript
interface PaginationQuery {
page?: number; // default: 1
limit?: number; // default: 10, max: 100
sort?: string; // campo a ordenar
order?: 'ASC' | 'DESC'; // default: 'DESC'
}
interface PaginatedResponse<T> {
data: T[];
meta: {
page: number;
limit: number;
total: number;
totalPages: number;
};
}
Patron de Filtros
interface FilterQuery {
search?: string; // busqueda full-text
status?: string; // filtro por estado
from?: string; // fecha inicio (ISO)
to?: string; // fecha fin (ISO)
}
Endpoints REST Estandar
Cada modulo CRUD expone:
| Metodo | Ruta | Descripcion |
|---|---|---|
| GET | /[recurso] | Listar con paginacion |
| GET | /[recurso]/:id | Obtener por ID |
| POST | /[recurso] | Crear nuevo |
| PATCH | /[recurso]/:id | Actualizar parcial |
| DELETE | /[recurso]/:id | Eliminar (soft delete) |
Roadmap: Clases Base
Implementacion Futura Planificada
Se planea implementar clases base reutilizables:
- BaseEntity - Campos comunes (id, timestamps, tenant_id)
- BaseCrudService - Operaciones CRUD genericas
- BaseCrudController - Endpoints REST estandar
- BaseDto - Validaciones comunes
Estado: Pendiente de implementacion Prioridad: Baja (cada modulo funciona correctamente de forma independiente)
Referencias
- Ver implementaciones en:
apps/backend/src/modules/*/ - Ejemplo recomendado:
modules/storage/(patron mas limpio)
**Validacion:**
```bash
grep "Estado.*Documentacion" docs/01-modulos/SAAS-012-crud-base.md
EJECUCION-004: SAAS-002-tenants.md
Ubicacion: docs/01-modulos/SAAS-002-tenants.md
Cambios a realizar:
Agregar seccion sobre Settings:
## Configuraciones de Tenant
Las configuraciones de cada tenant se almacenan en el campo `settings` (JSONB)
de la tabla `tenants.tenants`.
### Acceso via API
Las configuraciones se obtienen y actualizan junto con el tenant:
| Metodo | Ruta | Descripcion |
|--------|------|-------------|
| GET | /tenants/current | Obtiene tenant actual (incluye settings) |
| PATCH | /tenants/current | Actualiza tenant (puede incluir settings) |
### Estructura del Campo Settings
```json
{
"branding": {
"logo_url": "https://...",
"primary_color": "#3B82F6",
"company_name": "Mi Empresa"
},
"notifications": {
"email_enabled": true,
"push_enabled": false,
"digest_frequency": "daily"
},
"features": {
"ai_enabled": true,
"whatsapp_enabled": false
}
}
Nota sobre Endpoints Dedicados
Los endpoints dedicados /tenants/current/settings estan planificados pero
no implementados actualmente. Usar PATCH /tenants/current para actualizar settings.
**Validacion:**
```bash
grep "settings.*JSONB" docs/01-modulos/SAAS-002-tenants.md
EJECUCION-005: SAAS-006-ai-integration.md
Ubicacion: docs/01-modulos/SAAS-006-ai-integration.md
Cambios a realizar:
Agregar campos adicionales en tabla ai.usage:
## Tabla: ai.usage
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| id | UUID | Identificador unico |
| tenant_id | UUID | Tenant propietario |
| config_id | UUID | Configuracion usada |
| model | VARCHAR | Modelo utilizado |
| model_type | ai_model_type | chat, completion, embedding, image |
| request_id | VARCHAR | ID unico de request |
| endpoint | VARCHAR | Endpoint llamado |
| input_tokens | INTEGER | Tokens de entrada |
| output_tokens | INTEGER | Tokens de salida |
| cost | DECIMAL | Costo estimado |
| latency_ms | INTEGER | Latencia en ms |
| status | usage_status | pending, completed, failed, cancelled |
| error_message | TEXT | Mensaje de error (si fallo) |
| metadata | JSONB | Metadata adicional |
| created_at | TIMESTAMP | Fecha de uso |
Validacion:
grep "model_type" docs/01-modulos/SAAS-006-ai-integration.md
EJECUCION-006: SAAS-003-users.md
Ubicacion: docs/01-modulos/SAAS-003-users.md
Cambios a realizar:
Actualizar seccion de roles para reflejar modelo flexible:
## Sistema de Roles (RBAC)
### Modelo de Datos
El sistema usa un modelo flexible de roles basado en tablas:
- `users.roles` - Definicion de roles (custom por tenant)
- `users.user_roles` - Asignacion usuario-rol (many-to-many)
- `users.permissions` - Permisos disponibles
- `users.role_permissions` - Permisos por rol
### Roles Sugeridos
Aunque los roles son flexibles, se recomienda crear:
| Rol | Descripcion | Permisos Tipicos |
|-----|-------------|------------------|
| owner | Propietario del tenant | Todos |
| admin | Administrador | Gestion usuarios, billing, settings |
| member | Miembro estandar | Lectura, escritura propia |
| viewer | Solo lectura | Lectura |
### Nota
Los roles NO son un enum fijo. Cada tenant puede definir sus propios roles
con permisos personalizados.
Validacion:
grep "modelo flexible" docs/01-modulos/SAAS-003-users.md
EJECUCION-007: SAAS-001-auth.md
Ubicacion: docs/01-modulos/SAAS-001-auth.md
Cambios a realizar (multiples):
-
Metadata - verificar estado Completado
-
Mover OAuth a Roadmap:
## Roadmap
### OAuth 2.0 (Planificado)
Autenticacion con proveedores externos:
| Proveedor | Estado |
|-----------|--------|
| Google | Planificado |
| Microsoft | Planificado |
| GitHub | Planificado |
| Apple | Planificado |
**Endpoints planificados:**
- POST /auth/oauth/:provider - Iniciar flujo OAuth
- GET /auth/oauth/:provider/callback - Callback OAuth
### MFA - Multi-Factor Authentication (Planificado)
Autenticacion de dos factores via TOTP:
**Endpoints planificados:**
- POST /auth/mfa/setup - Configurar MFA
- POST /auth/mfa/verify - Verificar codigo
- DELETE /auth/mfa - Desactivar MFA
### Session Management (Planificado)
Gestion de sesiones activas:
**Endpoints planificados:**
- GET /auth/sessions - Listar sesiones activas
- DELETE /auth/sessions/:id - Revocar sesion especifica
- En seccion Endpoints, mantener solo los implementados:
- POST /auth/register
- POST /auth/login
- POST /auth/logout
- POST /auth/logout-all
- POST /auth/refresh
- POST /auth/password/forgot
- POST /auth/password/reset
- POST /auth/verify-email
- GET /auth/me
- Agregar nota en User Entity:
## Entidad User
### Campos Implementados
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| id | UUID | Identificador |
| tenant_id | UUID | Tenant |
| email | VARCHAR | Email unico |
| password_hash | VARCHAR | Hash bcrypt |
| first_name | VARCHAR | Nombre |
| last_name | VARCHAR | Apellido |
| status | user_status | pending, active, suspended, deleted |
| email_verified | BOOLEAN | Email verificado |
| created_at | TIMESTAMP | Creacion |
| updated_at | TIMESTAMP | Actualizacion |
### Campos Planificados (No Implementados)
- mfa_secret, mfa_enabled - Para MFA
- failed_login_attempts, locked_until - Para proteccion brute force
Validacion:
grep "Roadmap" docs/01-modulos/SAAS-001-auth.md
grep "Planificado" docs/01-modulos/SAAS-001-auth.md
EJECUCION-008: SAAS-004-billing.md
Ubicacion: docs/01-modulos/SAAS-004-billing.md
Cambios a realizar (multiples):
- Agregar seccion Enums con ambos subscription_status:
## Enums de Billing
### tenants.subscription_status
Estado general del tenant respecto a su suscripcion:
| Valor | Descripcion |
|-------|-------------|
| trialing | En periodo de prueba |
| active | Suscripcion activa |
| past_due | Pago atrasado |
| cancelled | Cancelado |
| unpaid | Sin pago |
### billing.subscription_status
Estado interno del sistema de billing:
| Valor | Descripcion |
|-------|-------------|
| trial | En trial |
| active | Activo |
| past_due | Pago atrasado |
| cancelled | Cancelado |
| expired | Expirado |
**Nota:** El sistema usa `tenants.subscription_status` para el estado visible
al usuario y `billing.subscription_status` para logica interna de billing.
- Agregar tabla payment_methods:
## Tabla: billing.payment_methods
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| id | UUID | Identificador |
| tenant_id | UUID | Tenant propietario |
| type | payment_method_type | card, bank_transfer, oxxo |
| provider | VARCHAR | stripe, conekta, etc. |
| external_payment_method_id | VARCHAR | ID en proveedor |
| card_brand | VARCHAR | Visa, Mastercard, etc. |
| card_last4 | VARCHAR | Ultimos 4 digitos |
| card_exp_month | INTEGER | Mes expiracion |
| card_exp_year | INTEGER | Año expiracion |
| is_default | BOOLEAN | Metodo por defecto |
| created_at | TIMESTAMP | Creacion |
### Endpoints Payment Methods
| Metodo | Ruta | Descripcion |
|--------|------|-------------|
| GET | /billing/payment-methods | Listar metodos de pago |
| POST | /billing/payment-methods | Agregar metodo (via Stripe) |
| DELETE | /billing/payment-methods/:id | Eliminar metodo |
| PATCH | /billing/payment-methods/:id/default | Establecer por defecto |
- Completar campos de Invoice:
## Tabla: billing.invoices
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| id | UUID | Identificador |
| tenant_id | UUID | Tenant |
| subscription_id | UUID | Suscripcion relacionada |
| stripe_invoice_id | VARCHAR | ID en Stripe |
| invoice_number | VARCHAR | Numero factura (INV-YYYYMM-XXXXXX) |
| subtotal | DECIMAL | Subtotal |
| tax | DECIMAL | Impuestos |
| discount | DECIMAL | Descuento |
| total | DECIMAL | Total |
| amount_paid | DECIMAL | Monto pagado |
| amount_due | DECIMAL | Monto pendiente |
| currency | VARCHAR | Moneda (USD, MXN, etc.) |
| status | invoice_status | draft, open, paid, void, uncollectible |
| invoice_date | DATE | Fecha de factura |
| due_date | DATE | Fecha de vencimiento |
| period_start | TIMESTAMP | Inicio periodo |
| period_end | TIMESTAMP | Fin periodo |
| paid_at | TIMESTAMP | Fecha de pago |
| invoice_pdf_url | VARCHAR | URL del PDF |
| hosted_invoice_url | VARCHAR | URL factura Stripe |
| customer_name | VARCHAR | Nombre cliente |
| customer_email | VARCHAR | Email cliente |
| billing_address | JSONB | Direccion de facturacion |
| created_at | TIMESTAMP | Creacion |
- Corregir nomenclatura trial:
### Campos de Trial en Subscriptions
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| trial_start | TIMESTAMP | Inicio del trial |
| trial_end | TIMESTAMP | Fin del trial |
Validacion:
grep "payment_methods" docs/01-modulos/SAAS-004-billing.md
grep "tenants.subscription_status" docs/01-modulos/SAAS-004-billing.md
EJECUCION-009: SAAS-007-notifications.md
Ubicacion: docs/01-modulos/SAAS-007-notifications.md
Cambios a realizar:
Agregar seccion Version 2.0:
## Version 2.0 (Implementada)
### Nuevos Componentes
#### DevicesController
Gestion de dispositivos para push notifications:
| Metodo | Ruta | Descripcion |
|--------|------|-------------|
| GET | /notifications/devices | Listar dispositivos |
| POST | /notifications/devices | Registrar dispositivo |
| DELETE | /notifications/devices/:id | Eliminar dispositivo |
#### NotificationsGateway (WebSocket)
Gateway para notificaciones en tiempo real:
- Namespace: `/notifications`
- Eventos: `notification`, `read`, `delete`
- Autenticacion via JWT en handshake
#### NotificationQueueService
Procesamiento asincrono de notificaciones:
- Cola BullMQ para envios masivos
- Reintentos automaticos
- Dead letter queue
### Tablas Adicionales v2.0
| Tabla | Descripcion |
|-------|-------------|
| notifications.user_devices | Dispositivos registrados para push |
| notifications.notification_queue | Cola de envio |
| notifications.notification_logs | Historial de envios |
### Integracion WhatsApp
Las notificaciones pueden enviarse via WhatsApp usando el canal `whatsapp`.
Ver [SAAS-014-whatsapp.md](./SAAS-014-whatsapp.md) para configuracion.
Validacion:
grep "Version 2.0" docs/01-modulos/SAAS-007-notifications.md
grep "WebSocket" docs/01-modulos/SAAS-007-notifications.md
EJECUCION-010: MASTER_INVENTORY.yml
Ubicacion: orchestration/inventarios/MASTER_INVENTORY.yml
Cambios a realizar:
- Corregir conteo de tablas:
metricas:
database_tables: 24 # Era 39
- Agregar seccion modulos_infraestructura:
modulos_infraestructura:
- id: "INFRA-001"
nombre: "health"
descripcion: "Health check y liveness probes"
estado: "completado"
backend: "apps/backend/src/modules/health/"
- id: "INFRA-002"
nombre: "onboarding"
descripcion: "Wizard de onboarding para nuevos tenants"
estado: "completado"
backend: "apps/backend/src/modules/onboarding/"
sp: 8
- id: "INFRA-003"
nombre: "rbac"
descripcion: "Role-Based Access Control"
estado: "completado"
backend: "apps/backend/src/modules/rbac/"
nota: "Sub-modulo integrado con SAAS-003"
- id: "INFRA-004"
nombre: "superadmin"
descripcion: "Portal de super administracion"
estado: "completado"
backend: "apps/backend/src/modules/superadmin/"
frontend: "apps/frontend/src/pages/superadmin/"
Validacion:
grep "database_tables: 24" orchestration/inventarios/MASTER_INVENTORY.yml
grep "modulos_infraestructura" orchestration/inventarios/MASTER_INVENTORY.yml
EJECUCION-011: DATABASE_INVENTORY.yml
Ubicacion: orchestration/inventarios/DATABASE_INVENTORY.yml
Cambios a realizar:
- Corregir conteo de tablas:
resumen:
total_tablas: 24 # Era 39
- Actualizar conteo de enums:
resumen:
total_enums: 32 # Era 29
Validacion:
grep "total_tablas: 24" orchestration/inventarios/DATABASE_INVENTORY.yml
grep "total_enums: 32" orchestration/inventarios/DATABASE_INVENTORY.yml
EJECUCION-012: Archivos Adicionales
PROJECT-STATUS.md:
| Database | Completado | 12 schemas, 24 tablas (incluye WhatsApp), RLS |
_MAP.md:
**Total:** 12 schemas, 24 tablas
CONTEXT-MAP.yml: Agregar referencia a modulos_infraestructura si aplica.
3. Orden Final de Ejecucion
| Paso | Archivo | Tiempo | Acumulado |
|---|---|---|---|
| 1 | SAAS-008-audit-logs.md | 10 min | 10 min |
| 2 | SAAS-009-feature-flags.md | 5 min | 15 min |
| 3 | SAAS-012-crud-base.md | 25 min | 40 min |
| 4 | SAAS-002-tenants.md | 15 min | 55 min |
| 5 | SAAS-006-ai-integration.md | 10 min | 1h 05min |
| 6 | SAAS-003-users.md | 15 min | 1h 20min |
| 7 | SAAS-001-auth.md | 35 min | 1h 55min |
| 8 | SAAS-004-billing.md | 40 min | 2h 35min |
| 9 | SAAS-007-notifications.md | 25 min | 3h 00min |
| 10 | MASTER_INVENTORY.yml | 15 min | 3h 15min |
| 11 | DATABASE_INVENTORY.yml | 5 min | 3h 20min |
| 12 | Otros (STATUS, MAP, CONTEXT) | 10 min | 3h 30min |
Total: 3h 30min
4. Checklist de Ejecucion
- EJECUCION-001: SAAS-008-audit-logs.md
- EJECUCION-002: SAAS-009-feature-flags.md
- EJECUCION-003: SAAS-012-crud-base.md
- EJECUCION-004: SAAS-002-tenants.md
- EJECUCION-005: SAAS-006-ai-integration.md
- EJECUCION-006: SAAS-003-users.md
- EJECUCION-007: SAAS-001-auth.md
- EJECUCION-008: SAAS-004-billing.md
- EJECUCION-009: SAAS-007-notifications.md
- EJECUCION-010: MASTER_INVENTORY.yml
- EJECUCION-011: DATABASE_INVENTORY.yml
- EJECUCION-012: Archivos adicionales
Estado: LISTO PARA EJECUCION
Creado por: Claude Code Fecha: 2026-01-10