trading-platform/orchestration/tareas/TASK-2026-02-05-ANALISIS-VALIDACION-MODELADO-BD/entregables/RECOMENDACIONES-MODELADO.md
Adrian Flores Cortes b9098ca91c [TASK-2026-02-05-ANALISIS-VALIDACION-MODELADO-BD] docs: Complete 6-phase database modeling analysis
Comprehensive analysis of 101 DDL tables across 11 schemas:
- Phase 1-2: Schema validation, 37 gaps cataloged (3 resolved)
- Phase 3: Integrity audit (80 FKs, 89 CHECKs, 17 issues: 2 CRIT/5 HIGH)
- Phase 4: DDL-Backend mapping (84% interfaces, 75% services, 61% controllers)
- Phase 5: Documentation purge catalog (201 files analyzed)
- Phase 6: Remediation plan (4 sprints, 204h)

Key finding: Backend uses raw SQL + pg Pool (NOT TypeORM).
13 deliverables + updated inventories to v2.0.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:48:45 -06:00

214 lines
7.6 KiB
Markdown

# RECOMENDACIONES DE MODELADO - Trading Platform
**Tarea:** TASK-2026-02-05-ANALISIS-VALIDACION-MODELADO-BD
**Fecha:** 2026-02-05
**Perfil:** Especialista en Base de Datos y Modelado de Datos
---
## R1. Consolidar Catalogos de Simbolos (PRIORIDAD ALTA)
**Problema:** `trading.symbols` (UUID PK) y `market_data.tickers` (SERIAL PK) son catalogos
paralelos del mismo concepto con PKs incompatibles.
**Recomendacion:**
1. Designar `trading.symbols` como tabla maestra (ya usa UUID, mas campos)
2. Agregar campos ML de tickers a symbols: `is_ml_enabled`, `polygon_ticker`, `supported_timeframes`
3. Migrar `market_data.tickers` a vista o tabla dependiente con FK a `trading.symbols`
4. Actualizar todas las referencias de `market_data.tickers.id` (SERIAL) a usar `trading.symbols.id` (UUID)
**Impacto:** Afecta ml schema, market_data schema, data-service Python
**Esfuerzo:** 12h (4h analisis + 8h implementacion)
---
## R2. Ejecutar Migraciones de Enums (PRIORIDAD ALTA)
**Problema:** Existen archivos de migracion para 2 de 3 conflictos, pero estan comentados y
nunca se ejecutaron.
**Hallazgo clave:** Ambos archivos de migracion existen pero son **solo documentacion** (SQL comentado).
`public.trading_timeframe` ya fue creado en `00-global-types.sql` pero las tablas no fueron migradas.
**Recomendacion por conflicto:**
1. **transaction_type (CONF-001, ALTA):** NO renombrar (breaking change). Mantener separados
con calificacion de schema estricta. Los schemas son separados y sirven propositos distintos.
Documentar la distincion en backend y enforcer `schema.enum` en todas las queries.
2. **timeframe (DUP-001, MEDIA):** `public.trading_timeframe` ya existe con 9 valores.
Ejecutar migracion de columnas en 3 tablas: `trading.bots`, `trading.signals`, `trading.drawing_tools`.
Non-breaking change (valores compatibles). Luego DROP tipos viejos.
3. **risk_profile (DUP-002, BAJA):** Valores identicos en ambos schemas. Opcional:
crear `public.risk_profile` para consistencia. No es urgente.
**Secuencia de ejecucion (solo timeframe - unico ejecutable sin riesgo):**
```sql
-- Paso 1: Migrar trading.bots.timeframe
ALTER TABLE trading.bots ADD COLUMN timeframe_new public.trading_timeframe;
UPDATE trading.bots SET timeframe_new = timeframe::text::public.trading_timeframe;
ALTER TABLE trading.bots DROP COLUMN timeframe;
ALTER TABLE trading.bots RENAME COLUMN timeframe_new TO timeframe;
-- Paso 2: Repetir para trading.signals y trading.drawing_tools
-- Paso 3: DROP TYPE trading.timeframe; DROP TYPE market_data.timeframe;
```
---
## R3. Agregar Foreign Keys Cross-Schema (PRIORIDAD ALTA)
**Problema:** Relaciones logicas entre schemas no estan formalizadas con FK.
**Recomendacion:**
### R3.1 investment.accounts -> financial.wallets
```sql
ALTER TABLE investment.accounts
ADD COLUMN wallet_id UUID REFERENCES financial.wallets(id);
```
Nota: La columna `wallet_id` ya existe en el DDL actual de `investment.accounts`. Verificar si el FK esta creado.
### R3.2 trading.bots -> financial.wallets
```sql
ALTER TABLE trading.bots
ADD COLUMN wallet_id UUID REFERENCES financial.wallets(id);
```
Para vincular capital de bots con wallets formalmente.
### R3.3 market_data.tickers -> trading.symbols
```sql
ALTER TABLE market_data.tickers
ADD COLUMN symbol_id UUID REFERENCES trading.symbols(id);
```
Vincula catalogos hasta que se consoliden (R1).
---
## R4. Documentar feature_flags Schema (PRIORIDAD ALTA)
**Problema:** Schema completo invisible para backend y documentacion.
**Recomendacion:**
1. Agregar a CLAUDE.md del proyecto en la seccion de schemas
2. Crear entity `Flag` en backend
3. Crear servicio `FeatureFlagService` con cache Redis
4. Documentar tabla `flags` en docs/ con ET (especificacion tecnica)
5. Integrar en middleware de Express para feature gating
**Patron sugerido:**
```typescript
// Middleware
const featureFlag = async (flagName: string) => {
const flag = await featureFlagService.getFlag(flagName);
return flag?.is_enabled ?? false;
};
```
---
## R5. Estandarizar Nomenclatura (PRIORIDAD MEDIA)
**Problema:** Inconsistencias en nombres de campos entre schemas.
| Caso | Tabla A | Tabla B | Recomendacion |
|------|---------|---------|---------------|
| asset_type vs asset_class | market_data.tickers | trading.symbols | Usar `asset_class` |
| strategy_type (VARCHAR) | trading.bots | - | Considerar FK a catalogo |
| timeframe (multiples) | public, trading, market_data | - | Consolidar en 1 enum |
---
## R6. Crear Servicios para audit Schema (PRIORIDAD MEDIA)
**Problema:** 7 tablas de audit sin ningun servicio backend (0% coherencia).
**Recomendacion:** Crear un modulo audit con:
1. `AuditService` - queries sobre audit_logs, data_access_logs
2. `SecurityEventService` - queries sobre security_events
3. `TradingAuditService` - queries sobre trading_audit
4. `ComplianceService` - queries sobre compliance_logs
5. `AuditController` - endpoints admin-only con paginacion
**Endpoints sugeridos:**
```
GET /api/admin/audit/logs?user_id=&event_type=&from=&to=&page=&limit=
GET /api/admin/audit/security?severity=&from=&to=
GET /api/admin/audit/trading?bot_id=&from=&to=
GET /api/admin/audit/compliance?type=&status=
GET /api/admin/audit/export?format=csv|json&from=&to=
```
---
## R7. Patron de Soft Delete (PRIORIDAD BAJA)
**Problema:** `financial.wallets` usa `ON DELETE RESTRICT` en FK a `auth.users`, lo que
impide eliminar usuarios con wallet.
**Recomendacion:**
1. Documentar como decision arquitectural (no es bug)
2. Implementar soft delete: agregar `deleted_at TIMESTAMPTZ` a `auth.users`
3. Actualizar queries para filtrar `WHERE deleted_at IS NULL`
4. Mantener RESTRICT para proteger integridad financiera
---
## R8. Indices Compuestos para Performance (PRIORIDAD BAJA)
**Recomendacion de indices adicionales:**
```sql
-- Alertas activas por usuario y simbolo (query frecuente)
CREATE INDEX idx_price_alerts_user_symbol_active
ON trading.price_alerts(user_id, symbol_id)
WHERE status = 'active';
-- Predicciones recientes por simbolo y tipo
CREATE INDEX idx_predictions_symbol_type_created
ON ml.predictions(symbol, prediction_type, created_at DESC);
-- Enrollments activos por usuario
CREATE INDEX idx_enrollments_user_active
ON education.enrollments(user_id)
WHERE status IN ('active', 'in_progress');
-- OHLCV queries recientes
CREATE INDEX idx_ohlcv_5m_recent
ON market_data.ohlcv_5m(symbol, timestamp DESC);
```
---
## R9. Considerar Particionamiento para Tablas de Alto Volumen (FUTURO)
Las siguientes tablas pueden beneficiarse de particionamiento por fecha:
| Tabla | Razon | Estrategia |
|-------|-------|------------|
| market_data.ohlcv_5m | Alto volumen (288 registros/dia/simbolo) | Range partition por mes |
| market_data.ohlcv_15m | Alto volumen (96 registros/dia/simbolo) | Range partition por mes |
| audit.audit_logs | Crecimiento continuo | Range partition por mes |
| audit.api_request_logs | Alto volumen por request | Range partition por semana |
---
## Resumen de Prioridades
| # | Recomendacion | Prioridad | Esfuerzo | Impacto |
|---|---------------|-----------|----------|---------|
| R1 | Consolidar catalogos simbolos | ALTA | 12h | Elimina duplicacion |
| R2 | Ejecutar migraciones enums | ALTA | 5h | Elimina 3 conflictos |
| R3 | Agregar FKs cross-schema | ALTA | 4h | Integridad referencial |
| R4 | Documentar feature_flags | ALTA | 8h | Schema invisible |
| R5 | Estandarizar nomenclatura | MEDIA | 2h | Consistencia |
| R6 | Servicios audit | MEDIA | 32h | 0% -> 100% coherencia |
| R7 | Soft delete pattern | BAJA | 4h | Mejora UX admin |
| R8 | Indices compuestos | BAJA | 2h | Performance |
| R9 | Particionamiento | FUTURO | 16h | Escalabilidad |
---
*Generado por Claude Code (Opus 4.6) - TASK-2026-02-05-ANALISIS-VALIDACION-MODELADO-BD*