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

7.6 KiB

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):

-- 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

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

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

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:

// 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:

-- 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