# Reporte de Análisis DDL - Trading Platform **Fecha:** 2026-02-03 **Agente:** Claude Code **Tipo:** ANALYSIS (C+A+P) **Estado:** FASE 1-2 COMPLETADAS --- ## 1. RESUMEN EJECUTIVO Se completó el análisis de conflictos DDL y gaps entre el modelado de datos y los requerimientos. ### Métricas Clave | Métrica | Valor Actual | Objetivo | Delta | |---------|--------------|----------|-------| | Schemas PostgreSQL | 10 | 10 | ✓ | | Tablas DDL | 89 | ~95 | +6 nuevas | | Coherencia DDL-Backend | 85% | 90% | +5% | | Coherencia DDL-Requerimientos | 72% | 85% | +13% | ### Hallazgos Principales - **3 conflictos** identificados (2 no requieren cambios) - **6 gaps DDL** confirmados - **0 tablas** a eliminar - **6 tablas/campos** a agregar --- ## 2. ANÁLISIS DE CONFLICTOS ### C1: Catálogos Duplicados ⚠️ **Problema:** `trading.symbols` vs `market_data.tickers` | Aspecto | trading.symbols | market_data.tickers | |---------|-----------------|---------------------| | ID Type | UUID | SERIAL | | Columnas | 13 | 11 | | Precisión | price_precision, quantity_precision | - | | ML | - | is_ml_enabled, polygon_ticker | | FK | Referenciada por watchlist_items | No referenciada | **Recomendación:** Consolidar en `trading.symbols` como tabla maestra. - Agregar `is_ml_enabled BOOLEAN DEFAULT true` - Agregar `polygon_ticker VARCHAR(20)` - Agregar `supported_timeframes VARCHAR[]` - Deprecar `market_data.tickers` gradualmente **Impacto:** Medio - Requiere migración de FK en market_data queries. --- ### C2: Sistemas de Transacciones Paralelos ✓ **Problema:** `financial.wallet_transactions` vs `investment.transactions` | Aspecto | financial.wallet_transactions | investment.transactions | |---------|-------------------------------|-------------------------| | Tipos | 9 (deposit, withdrawal, transfer_in/out, fee, refund, earning, distribution, bonus) | 3 (deposit, withdrawal, distribution) | | Propósito | Movimientos de wallet genéricos | Operaciones PAMM específicas | | Precisión | DECIMAL(20,8) | DECIMAL(15,2) | **Análisis:** Son sistemas **COMPLEMENTARIOS**, no duplicados. - `wallet_transactions`: Operaciones a nivel de wallet (cualquier tipo) - `investment.transactions`: Operaciones específicas de cuentas PAMM **Recomendación:** MANTENER separados. Documentar patrón en arquitectura. - Opcional: FK `investment.transactions.wallet_transaction_id → wallet_transactions.id` **Impacto:** Ninguno - Diseño intencional. --- ### C3: Enums transaction_type Divergentes ✓ **Problema:** Mismo nombre de enum, valores diferentes | Schema | Valores | |--------|---------| | financial | deposit, withdrawal, transfer_in, transfer_out, fee, refund, earning, distribution, bonus | | investment | deposit, withdrawal, distribution | **Análisis:** Intencional por dominio. Cada schema maneja su propio conjunto de tipos de transacción. **Recomendación:** MANTENER separados. Documentar en ADR como "domain-specific by design". **Impacto:** Ninguno. --- ### C5: Enums Duplicados ⚠️ **Problema 1:** `risk_profile` duplicado ```sql -- investment.risk_profile CREATE TYPE investment.risk_profile AS ENUM ('conservative', 'moderate', 'aggressive'); -- portfolio.risk_profile (IDÉNTICO) CREATE TYPE portfolio.risk_profile AS ENUM ('conservative', 'moderate', 'aggressive'); ``` **Recomendación:** Considerar consolidar en `public.risk_profile` compartido. **Problema 2:** `timeframe` divergente | Schema | Valores | |--------|---------| | trading | 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w, **1M** | | market_data | 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w | **Recomendación:** Agregar `'1M'` a `market_data.timeframe`. **Impacto:** Bajo - Cambios menores. --- ## 3. GAPS DDL IDENTIFICADOS ### GAP-DDL-001: education.instructors ⭐ P1 **Épica:** OQI-002 (Educativo) **Estado Actual:** courses.instructor_id → auth.users (sin metadata de instructor) **DDL Propuesto:** ```sql CREATE TABLE education.instructors ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES auth.users(id), bio TEXT, avatar_url VARCHAR(500), specialties VARCHAR[], rating DECIMAL(3,2) CHECK (rating >= 0 AND rating <= 5), courses_count INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_instructors_user ON education.instructors(user_id); CREATE INDEX idx_instructors_rating ON education.instructors(rating); -- Actualizar courses para usar instructors ALTER TABLE education.courses DROP COLUMN instructor_name, ADD CONSTRAINT fk_courses_instructor FOREIGN KEY (instructor_id) REFERENCES education.instructors(id); ``` **Impacto:** RF-EDU-001 (Instructors) cubierto al 100%. --- ### GAP-DDL-002: education.courses.tags ⭐ P2 **DDL Propuesto:** ```sql ALTER TABLE education.courses ADD COLUMN tags VARCHAR[] DEFAULT '{}'; CREATE INDEX idx_courses_tags ON education.courses USING GIN(tags); COMMENT ON COLUMN education.courses.tags IS 'Tags para búsqueda y filtrado de cursos'; ``` **Impacto:** Mejora búsqueda y filtrado de cursos. --- ### GAP-DDL-003: trading.price_alerts ⭐ P1 **Épica:** OQI-003 (Trading) **DDL Propuesto:** ```sql CREATE TABLE trading.price_alerts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES auth.users(id), symbol_id UUID NOT NULL REFERENCES trading.symbols(id), condition VARCHAR(10) NOT NULL CHECK (condition IN ('above', 'below', 'crosses')), target_price DECIMAL(20,8) NOT NULL, is_active BOOLEAN DEFAULT true, triggered_at TIMESTAMPTZ, notification_sent BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_price_alerts_user ON trading.price_alerts(user_id); CREATE INDEX idx_price_alerts_symbol ON trading.price_alerts(symbol_id); CREATE INDEX idx_price_alerts_active ON trading.price_alerts(is_active) WHERE is_active = true; COMMENT ON TABLE trading.price_alerts IS 'Alertas de precio configuradas por usuarios'; ``` **Impacto:** Habilita notificaciones de precio para usuarios. --- ### GAP-DDL-004: financial.refunds ⭐ P1 **Épica:** OQI-005 (Pagos) **DDL Propuesto:** ```sql CREATE TABLE financial.refunds ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), payment_id UUID NOT NULL REFERENCES financial.payments(id), amount DECIMAL(20,8) NOT NULL CHECK (amount > 0), reason VARCHAR(255), status financial.payment_status DEFAULT 'pending', stripe_refund_id VARCHAR(255), requested_by UUID REFERENCES auth.users(id), approved_by UUID REFERENCES auth.users(id), created_at TIMESTAMPTZ DEFAULT NOW(), processed_at TIMESTAMPTZ, CONSTRAINT refund_amount_valid CHECK (amount > 0) ); CREATE INDEX idx_refunds_payment ON financial.refunds(payment_id); CREATE INDEX idx_refunds_status ON financial.refunds(status); CREATE INDEX idx_refunds_stripe ON financial.refunds(stripe_refund_id); COMMENT ON TABLE financial.refunds IS 'Registro de reembolsos para compliance y tracking'; ``` **Impacto:** Compliance para partial refunds y auditoría. --- ### GAP-DDL-005: investment.agent_executions ⭐ P1 **Épica:** OQI-004 (Inversiones) **DDL Propuesto:** ```sql CREATE TABLE investment.agent_executions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID NOT NULL REFERENCES investment.accounts(id), agent_type investment.trading_agent NOT NULL, execution_type VARCHAR(20) NOT NULL CHECK (execution_type IN ('trade', 'rebalance', 'distribution', 'stop_loss')), symbol VARCHAR(20), side VARCHAR(4) CHECK (side IN ('buy', 'sell')), quantity DECIMAL(20,8), price DECIMAL(20,8), trade_details JSONB, pnl DECIMAL(20,8), executed_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_agent_exec_account ON investment.agent_executions(account_id); CREATE INDEX idx_agent_exec_type ON investment.agent_executions(agent_type); CREATE INDEX idx_agent_exec_date ON investment.agent_executions(executed_at DESC); COMMENT ON TABLE investment.agent_executions IS 'Tracking de ejecuciones de trading agents (Atlas, Orion, Nova)'; ``` **Impacto:** Trazabilidad completa de operaciones de agents. --- ### GAP-DDL-006: ml.predictions.overlay_data ⭐ P3 **DDL Propuesto:** ```sql ALTER TABLE ml.predictions ADD COLUMN overlay_data JSONB; COMMENT ON COLUMN ml.predictions.overlay_data IS 'Datos de overlay para visualización en charts'; ``` **Impacto:** Menor - Mejora visualización ML en frontend. --- ## 4. DOCUMENTACIÓN A ARCHIVAR ### Archivos Obsoletos Identificados | Archivo | Estado | Recomendación | |---------|--------|---------------| | Análisis previos en _archive/ | Ya archivados | Verificar | | TASK-2026-01-25-FRONTEND-MODULE-DOCS | Sin progreso | Evaluar cancelación | | TASK-2026-01-27-BLOCKER-001-TOKEN-REFRESH | Postergada | Mantener postergada | --- ## 5. PRÓXIMOS PASOS ### Fase 3: Implementación DDL 1. [ ] Crear archivos DDL para nuevas tablas 2. [ ] Agregar campos faltantes a tablas existentes 3. [ ] Actualizar enums (timeframe) 4. [ ] Recrear BD en WSL para validar ### Fase 4: Validación 1. [ ] Ejecutar `unified-recreate-db.sh trading-platform --drop` 2. [ ] Verificar 0 errores 3. [ ] Actualizar inventarios 4. [ ] Medir coherencia final --- ## 6. ARCHIVOS MODIFICADOS - `orchestration/analisis/coherencia/GAPS-TRACKING.yml` - Actualizado - `orchestration/tareas/2026-02-03/TASK-2026-02-03-DDL-VALIDATION/METADATA.yml` - Creado - `orchestration/tareas/2026-02-03/TASK-2026-02-03-DDL-VALIDATION/ANALYSIS-REPORT.md` - Creado --- *Reporte generado por Claude Code - Sistema SIMCO v4.0.0*