# ============================================================================== # Gaps Tracking - Trading Platform # Generated: 2026-01-27 # Updated: 2026-02-03 # ============================================================================== version: "1.1.0" project: "trading-platform" total_gaps: 24 completed_gaps: 0 in_progress_gaps: 6 # ============================================================================== # CONFLICTOS DDL (Nuevo - 2026-02-03) # ============================================================================== ddl_conflicts: - id: CONFLICT-C1 title: "Catálogos Duplicados: trading.symbols vs market_data.tickers" priority: "P1" status: "analizado" description: | Dos tablas de catálogo de símbolos con propósitos similares pero IDs diferentes: - trading.symbols: UUID, price_precision, min_quantity, max_quantity, exchange - market_data.tickers: SERIAL, is_ml_enabled, polygon_ticker, supported_timeframes recommendation: | Consolidar en trading.symbols como tabla maestra. Agregar campos ML de tickers (is_ml_enabled, polygon_ticker). market_data puede referenciar trading.symbols via FK. created_at: "2026-02-03" - id: CONFLICT-C2 title: "Sistemas de Transacciones Paralelos" priority: "P2" status: "analizado" description: | financial.wallet_transactions (9 tipos) vs investment.transactions (3 tipos). Son COMPLEMENTARIOS, no duplicados: - wallet_transactions: Movimientos de wallet genéricos - investment.transactions: Operaciones PAMM específicas recommendation: | MANTENER separados. Documentar patrón. Opcional: Agregar FK de investment.transactions → wallet_transactions. created_at: "2026-02-03" - id: CONFLICT-C5 title: "Enums Duplicados: risk_profile, timeframe divergente" priority: "P2" status: "analizado" description: | - investment.risk_profile = portfolio.risk_profile (IDÉNTICOS) - trading.timeframe tiene '1M', market_data.timeframe NO lo tiene recommendation: | - Considerar consolidar risk_profile en shared schema - Agregar '1M' a market_data.timeframe created_at: "2026-02-03" # ============================================================================== # GAPS DDL NUEVOS (2026-02-03) # ============================================================================== new_ddl_gaps: - id: GAP-DDL-001 title: "education.instructors - Tabla faltante" priority: "P1" status: "in_progress" epic: "OQI-002" description: | courses.instructor_id referencia auth.users directamente. Falta tabla dedicada con bio, avatar, specialties, rating. ddl_propuesto: | CREATE TABLE education.instructors ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES auth.users(id), bio TEXT, avatar_url VARCHAR(500), specialties VARCHAR[], rating DECIMAL(3,2), courses_count INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW() ); estimated_hours: 4 created_at: "2026-02-03" - id: GAP-DDL-002 title: "education.courses.tags - Campo faltante" priority: "P2" status: "in_progress" epic: "OQI-002" description: "Campo tags faltante para búsqueda/filtrado de cursos" ddl_propuesto: | ALTER TABLE education.courses ADD COLUMN tags VARCHAR[] DEFAULT '{}'; CREATE INDEX idx_courses_tags ON education.courses USING GIN(tags); estimated_hours: 2 created_at: "2026-02-03" - id: GAP-DDL-003 title: "trading.price_alerts - Tabla faltante" priority: "P1" status: "in_progress" epic: "OQI-003" description: "Falta tabla para alertas de precio y notificaciones de usuario" ddl_propuesto: | CREATE TABLE trading.price_alerts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES auth.users(id), symbol_id UUID REFERENCES trading.symbols(id), condition VARCHAR(10) NOT NULL, target_price DECIMAL(20,8) NOT NULL, is_active BOOLEAN DEFAULT true, triggered_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW() ); estimated_hours: 4 created_at: "2026-02-03" - id: GAP-DDL-004 title: "financial.refunds - Tabla faltante" priority: "P1" status: "in_progress" epic: "OQI-005" description: | Refunds embebidos en payments como campos. Para compliance y partial refunds se necesita tabla dedicada. ddl_propuesto: | CREATE TABLE financial.refunds ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), payment_id UUID REFERENCES financial.payments(id), amount DECIMAL(20,8) NOT NULL, reason VARCHAR(255), status VARCHAR(20) DEFAULT 'pending', stripe_refund_id VARCHAR(255), created_at TIMESTAMPTZ DEFAULT NOW(), processed_at TIMESTAMPTZ ); estimated_hours: 4 created_at: "2026-02-03" - id: GAP-DDL-005 title: "investment.agent_executions - Tabla faltante" priority: "P1" status: "in_progress" epic: "OQI-004" description: "Falta tracking de ejecuciones de trading agents (Atlas, Orion, Nova)" ddl_propuesto: | CREATE TABLE investment.agent_executions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID REFERENCES investment.accounts(id), agent_type VARCHAR(20) NOT NULL, execution_type VARCHAR(20), trade_details JSONB, pnl DECIMAL(20,8), executed_at TIMESTAMPTZ DEFAULT NOW() ); estimated_hours: 4 created_at: "2026-02-03" - id: GAP-DDL-006 title: "ml.predictions.overlay_data - Campo faltante" priority: "P3" status: "in_progress" epic: "OQI-006" description: "Campo específico para overlay_data de charts ML" ddl_propuesto: | ALTER TABLE ml.predictions ADD COLUMN overlay_data JSONB; estimated_hours: 1 created_at: "2026-02-03" # ============================================================================== # P1 - Gaps Críticos (Acción Inmediata) # ============================================================================== p1_gaps: - id: GAP-001 title: "Market Data OHLCV Service" priority: "P1" status: "pending" schema: "market_data" tables: - market_data.ohlcv_5m - market_data.ohlcv_15m description: | Las tablas OHLCV no tienen servicios backend. Los charts del frontend necesitan consultar estos datos via API REST. impact: "alto" effort: "medio" estimated_hours: 16 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/market-data/services/marketData.service.ts" type: "service" methods: - getOHLCV(symbol, timeframe, limit?) - getLatestCandles(symbol, timeframe) - getHistoricalData(symbol, from, to) - getCandlesByRange(symbol, timeframe, start, end) - file: "apps/backend/src/modules/market-data/types/market-data.types.ts" type: "interfaces" interfaces: - OHLCV - Timeframe - CandleQueryOptions - file: "apps/backend/src/modules/market-data/controllers/market-data.controller.ts" type: "controller" endpoints: - "GET /api/market-data/ohlcv/:symbol/:timeframe" - "GET /api/market-data/historical/:symbol" - file: "apps/backend/src/modules/market-data/market-data.module.ts" type: "module" tests: - file: "apps/backend/src/modules/market-data/services/marketData.service.spec.ts" - file: "apps/backend/src/modules/market-data/controllers/market-data.controller.spec.ts" dependencies: - market_data schema debe estar poblado con datos - Integración con data-service Python (opcional) acceptance_criteria: - "[ ] Servicio puede consultar ohlcv_5m y ohlcv_15m" - "[ ] Endpoint REST responde en <500ms para 100 candles" - "[ ] Tipos TypeScript correctamente definidos" - "[ ] Tests unitarios cubren >80%" - "[ ] Documentación Swagger completa" - "[ ] Frontend puede consumir endpoints" - id: GAP-002 title: "Notification Service y Push Tokens" priority: "P1" status: "pending" schema: "auth" tables: - auth.notifications - auth.user_push_tokens description: | Sistema de notificaciones existe en DDL pero sin servicios backend. Usuarios no pueden consultar ni gestionar notificaciones. impact: "alto" effort: "medio" estimated_hours: 20 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/notifications/services/notification.service.ts" type: "service" methods: - getUserNotifications(userId, filters?) - markAsRead(notificationId) - markAllAsRead(userId) - deleteNotification(notificationId) - sendNotification(userId, notification) - file: "apps/backend/src/modules/notifications/services/push.service.ts" type: "service" methods: - registerPushToken(userId, token, platform) - unregisterPushToken(tokenId) - sendPushNotification(userId, payload) - sendBulkPushNotifications(userIds, payload) - file: "apps/backend/src/modules/notifications/types/notification.types.ts" type: "interfaces" interfaces: - Notification - NotificationType - PushToken - PushPayload - file: "apps/backend/src/modules/notifications/controllers/notification.controller.ts" type: "controller" endpoints: - "GET /api/notifications" - "POST /api/notifications/:id/read" - "DELETE /api/notifications/:id" - "POST /api/notifications/push-token" - file: "apps/backend/src/modules/notifications/notifications.module.ts" type: "module" tests: - file: "apps/backend/src/modules/notifications/services/notification.service.spec.ts" - file: "apps/backend/src/modules/notifications/services/push.service.spec.ts" dependencies: - Firebase Cloud Messaging o OneSignal para push - WebSocket para notificaciones en tiempo real (opcional) acceptance_criteria: - "[ ] Usuarios pueden ver sus notificaciones" - "[ ] Usuarios pueden marcar como leídas" - "[ ] Push tokens se registran correctamente" - "[ ] Push notifications se envían vía FCM/OneSignal" - "[ ] Tests cubren casos principales" - "[ ] Frontend notifica en tiempo real" # ============================================================================== # P2 - Gaps Importantes (Corto Plazo) # ============================================================================== p2_gaps: - id: GAP-003 title: "Audit Service - Consultas de Logs" priority: "P2" status: "pending" schema: "audit" tables: - audit.audit_logs - audit.security_events - audit.trading_audit - audit.api_request_logs description: | Sistema de auditoría registra logs via triggers/middleware pero no hay servicios para consultarlos. Admin dashboard necesita estos datos. impact: "medio" effort: "grande" estimated_hours: 32 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/audit/services/audit.service.ts" type: "service" methods: - getAuditLogs(filters) - getSecurityEvents(filters) - getTradingAudit(botId, filters) - getAPIRequestLogs(filters) - exportAuditReport(from, to) - file: "apps/backend/src/modules/audit/types/audit.types.ts" type: "interfaces" - file: "apps/backend/src/modules/audit/controllers/audit.controller.ts" type: "controller" endpoints: - "GET /api/audit/logs" - "GET /api/audit/security-events" - "GET /api/audit/trading/:botId" - "GET /api/audit/export" acceptance_criteria: - "[ ] Admin puede consultar audit logs" - "[ ] Filtros por fecha, usuario, tipo de evento" - "[ ] Paginación para grandes volúmenes" - "[ ] Export a CSV/JSON" - "[ ] Endpoints protegidos (admin only)" - id: GAP-004 title: "Currency Exchange Service" priority: "P2" status: "pending" schema: "financial" tables: - financial.currency_exchange_rates description: | Sistema multi-moneda (USD, MXN, EUR) necesita servicio de conversión con sincronización automática de tasas de cambio. impact: "medio" effort: "medio" estimated_hours: 16 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/financial/services/currencyExchange.service.ts" type: "service" methods: - getExchangeRate(from, to, date?) - convertAmount(amount, from, to) - syncRatesFromAPI() - getHistoricalRates(from, to, startDate, endDate) - file: "apps/backend/src/modules/financial/types/currency.types.ts" type: "interfaces" dependencies: - API externa: CoinGecko, ExchangeRate-API, o similar - Cron job para sincronización diaria acceptance_criteria: - "[ ] Conversión USD <-> MXN <-> EUR" - "[ ] Sync automático de tasas diarias" - "[ ] Fallback a tasas anteriores si API falla" - "[ ] Cache de tasas recientes" - id: GAP-005 title: "Risk Assessment Service" priority: "P2" status: "pending" schema: "investment" tables: - investment.risk_questionnaire description: | Usuarios completan cuestionario de riesgo pero no hay servicio para gestionar respuestas ni calcular perfil. impact: "medio" effort: "medio" estimated_hours: 12 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/investment/services/riskAssessment.service.ts" type: "service" methods: - submitQuestionnaire(userId, answers) - calculateRiskProfile(answers) - getUserRiskProfile(userId) - retakeQuestionnaire(userId) acceptance_criteria: - "[ ] Usuarios pueden completar cuestionario" - "[ ] Perfil de riesgo se calcula automáticamente" - "[ ] Resultados se almacenan en risk_questionnaire table" - "[ ] Validación de respuestas" - id: GAP-006 title: "Course Reviews" priority: "P2" status: "pending" schema: "education" tables: - education.course_reviews description: | Tabla de reviews existe pero no hay endpoints para crear/consultar. impact: "bajo" effort: "pequeño" estimated_hours: 6 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/education/services/course.service.ts" type: "service" methods: - createReview(userId, courseId, rating, review) - getCourseReviews(courseId, pagination) - updateReview(reviewId, data) - deleteReview(reviewId) acceptance_criteria: - "[ ] Usuarios pueden crear reviews" - "[ ] Reviews se muestran en curso" - "[ ] Rating promedio se calcula" - "[ ] Validación: 1 review por usuario por curso" - id: GAP-007 title: "Login Attempts Tracking" priority: "P2" status: "pending" schema: "auth" tables: - auth.login_attempts description: | Tabla registra intentos de login pero no hay consultas para análisis de seguridad. impact: "bajo" effort: "pequeño" estimated_hours: 4 assigned_to: null created_at: "2026-01-27" due_date: null deliverables: - file: "apps/backend/src/modules/auth/services/token.service.ts" type: "service" methods: - getLoginAttempts(email?, ip?, limit) - getFailedAttempts(userId) - analyzeLoginPatterns(userId) acceptance_criteria: - "[ ] Admin puede consultar login attempts" - "[ ] Filtros por email, IP, fecha" - "[ ] Detección de patrones sospechosos" # ============================================================================== # P3 - Gaps Menores (Largo Plazo) # ============================================================================== p3_gaps: - id: GAP-008 title: "Distribution Runs Admin" priority: "P3" status: "pending" schema: "investment" tables: - investment.distribution_runs description: "Admin endpoint para gestionar distribution runs" impact: "bajo" effort: "pequeño" estimated_hours: 4 - id: GAP-009 title: "System Events Queries" priority: "P3" status: "pending" schema: "audit" tables: - audit.system_events - audit.data_access_logs description: "Consultas de system events en audit.service.ts" impact: "bajo" effort: "pequeño" estimated_hours: 4 - id: GAP-010 title: "Compliance Service (KYC/AML)" priority: "P3" status: "pending" schema: "audit" tables: - audit.compliance_logs description: "Futuro compliance.service.ts para KYC/AML" impact: "bajo" effort: "grande" estimated_hours: 40 - id: GAP-011 title: "Rate Limiting Config Admin" priority: "P3" status: "pending" schema: "auth" tables: - auth.rate_limiting_config description: "Admin endpoint para configurar rate limits" impact: "bajo" effort: "pequeño" estimated_hours: 4 # ============================================================================== # Estadísticas # ============================================================================== statistics: by_priority: P1: 6 # +4 nuevos DDL gaps P2: 7 # +2 conflictos P3: 5 # +1 gap menor by_status: pending: 11 in_progress: 6 # 6 gaps DDL nuevos analizado: 3 # 3 conflictos completed: 0 by_effort: pequeño: 8 medio: 6 grande: 1 total_estimated_hours: 181 # +19 horas para nuevos gaps # ============================================================================== # Notas de Tracking # ============================================================================== tracking_notes: | Este archivo debe actualizarse cuando: - Se inicia trabajo en un gap (status: in_progress) - Se completa un gap (status: completed) - Se reasigna prioridad de un gap - Se asigna desarrollador a un gap - Se estima nueva fecha de entrega Para marcar un gap como completado: 1. Cambiar status a "completed" 2. Agregar completed_at con fecha 3. Agregar pull_request con URL del PR 4. Validar que todos los acceptance_criteria estén cumplidos Formato para gaps completados: - id: GAP-XXX status: "completed" completed_at: "2026-XX-XX" completed_by: "Developer Name" pull_request: "https://github.com/org/repo/pull/XXX" review_status: "approved" last_updated: "2026-02-03" next_review: "2026-02-10" # ============================================================================== # Análisis 2026-02-03 - Resumen # ============================================================================== analysis_2026_02_03: agent: "Claude Code" archivos_analizados: 15 conflictos_identificados: 3 gaps_nuevos: 6 recomendaciones: - "Consolidar catálogos en trading.symbols" - "Mantener transaction systems separados (by design)" - "Considerar consolidar risk_profile en shared schema" - "Agregar 6 tablas/campos faltantes para cerrar gaps" coherencia_actual: ddl_backend: "85%" ddl_requerimientos: "72%" coherencia_objetivo: ddl_backend: "90%" ddl_requerimientos: "85%"