# ============================================================================== # ENTITIES CREATION PLAN # ============================================================================== # Task: TASK-2026-02-05-ANALISIS-VALIDACION-MODELADO-BD # Phase: 4 - Backend Architecture Analysis # Generated: 2026-02-05 # Agent: Backend Architecture Specialist (Claude Opus 4.6) # ============================================================================== # This plan covers: # 1. Missing TypeScript interfaces (type_interface) # 2. Missing Row types (row_type) for DB mapping # 3. Missing repositories (where pattern is established) # 4. Missing services and controllers # ============================================================================== metadata: project: trading-platform (OrbiQuant IA) backend_path: "apps/backend/src" architecture: "Express.js + Raw SQL (pg Pool)" entity_pattern: "TypeScript interfaces in modules/{module}/types/{module}.types.ts" row_type_pattern: "Interface with snake_case fields suffixed with 'Row'" repository_pattern: "Class in modules/{module}/repositories/{name}.repository.ts" date_generated: "2026-02-05" # ============================================================================== # PRIORITY LEVELS # ============================================================================== # P0 (CRITICAL): Missing interface for table that has active service/controller # P1 (HIGH): Missing Row type for tables with active CRUD operations # P2 (MEDIUM): Missing Row types for tables with read operations # P3 (LOW): Missing types for Python-managed or internal-only tables # ============================================================================== # ============================================================================== # PHASE 1: CRITICAL - Missing Type Interfaces (P0) # ============================================================================== # Tables that have NO TypeScript interface at all but need one. # Estimated effort: 2-4 hours total # ============================================================================== phase_1_missing_interfaces: title: "Create Missing TypeScript Interfaces" priority: P0 estimated_effort: "3 hours" total_items: 9 items: # -------------------------------------------------------------------------- # trading.trades - HIGH IMPACT # -------------------------------------------------------------------------- - id: ENT-001 table: trading.trades ddl_file: "apps/database/ddl/schemas/trading/tables/07-trades.sql" target_file: "apps/backend/src/modules/trading/types/order.types.ts" action: ADD_INTERFACE priority: P0 reason: "Active table for order execution tracking. Used by order.service.ts indirectly." interface_name: Trade columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: orderId, type: "string", ddl_type: "UUID", fk: "trading.orders(id)" } - { name: positionId, type: "string | null", ddl_type: "UUID", fk: "trading.positions(id)" } - { name: executedPrice, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: executedQuantity, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: commission, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: commissionAsset, type: "string", ddl_type: "VARCHAR(20)" } - { name: side, type: "OrderSide", ddl_type: "trading.order_side" } - { name: isMaker, type: "boolean", ddl_type: "BOOLEAN" } - { name: tradeSource, type: "string", ddl_type: "VARCHAR(50)" } - { name: externalTradeId, type: "string | null", ddl_type: "VARCHAR(100)" } - { name: executedAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: TradeRow dto_names: - CreateTradeDto dependencies: ["Order (order.types.ts)", "Position (MISSING - see ENT-002)"] # -------------------------------------------------------------------------- # trading.positions - NEEDS DEDICATED INTERFACE # -------------------------------------------------------------------------- - id: ENT-002 table: trading.positions ddl_file: "apps/database/ddl/schemas/trading/tables/06-positions.sql" target_file: "apps/backend/src/modules/trading/types/order.types.ts" action: ADD_INTERFACE priority: P0 reason: "Only PositionStatus enum exists. Full interface needed for 22-column table." interface_name: Position columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: userId, type: "string", ddl_type: "UUID", fk: "auth.users(id)" } - { name: botId, type: "string | null", ddl_type: "UUID", fk: "trading.bots(id)" } - { name: symbolId, type: "string", ddl_type: "UUID", fk: "trading.symbols(id)" } - { name: side, type: "OrderSide", ddl_type: "trading.order_side" } - { name: status, type: "PositionStatus", ddl_type: "trading.position_status" } - { name: entryPrice, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: currentPrice, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: exitPrice, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: quantity, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: filledQuantity, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: leverage, type: "number", ddl_type: "DECIMAL(5,2)" } - { name: stopLoss, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: takeProfit, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: trailingStopPercent, type: "number | null", ddl_type: "DECIMAL(5,2)" } - { name: unrealizedPnl, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: realizedPnl, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: commission, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: isPaper, type: "boolean", ddl_type: "BOOLEAN" } - { name: openedAt, type: "Date", ddl_type: "TIMESTAMPTZ" } - { name: closedAt, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } - { name: updatedAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: PositionRow dto_names: - CreatePositionDto - UpdatePositionDto - PositionFilters dependencies: ["OrderSide, PositionStatus (order.types.ts)", "Symbol (entity.types.ts)"] # -------------------------------------------------------------------------- # investment.distribution_runs # -------------------------------------------------------------------------- - id: ENT-003 table: investment.distribution_runs ddl_file: "apps/database/ddl/schemas/investment/tables/09-distribution_runs.sql" target_file: "apps/backend/src/modules/investment/types/investment.types.ts" action: ADD_INTERFACE priority: P0 reason: "System table needed for admin dashboard and batch monitoring." interface_name: DistributionRun columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: run_date, type: "Date", ddl_type: "DATE" } - { name: status, type: "string", ddl_type: "VARCHAR(20)" } - { name: total_accounts_processed, type: "number", ddl_type: "INTEGER" } - { name: total_distributed, type: "number", ddl_type: "DECIMAL(18,2)" } - { name: total_fees, type: "number", ddl_type: "DECIMAL(18,2)" } - { name: started_at, type: "Date", ddl_type: "TIMESTAMPTZ" } - { name: completed_at, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: error_message, type: "string | null", ddl_type: "TEXT" } - { name: created_at, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: DistributionRunRow dependencies: [] # -------------------------------------------------------------------------- # investment.agent_executions # -------------------------------------------------------------------------- - id: ENT-004 table: investment.agent_executions ddl_file: "apps/database/ddl/schemas/investment/tables/10-agent_executions.sql" target_file: "apps/backend/src/modules/investment/types/investment.types.ts" action: ADD_INTERFACE priority: P0 reason: "25-column table tracking trading agent executions. Critical for monitoring." interface_name: AgentExecution columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: account_id, type: "string", ddl_type: "UUID" } - { name: trading_agent, type: "TradingAgent", ddl_type: "investment.trading_agent" } - { name: execution_date, type: "Date", ddl_type: "DATE" } - { name: starting_balance, type: "number", ddl_type: "DECIMAL(18,2)" } - { name: ending_balance, type: "number", ddl_type: "DECIMAL(18,2)" } - { name: pnl, type: "number", ddl_type: "DECIMAL(18,2)" } - { name: pnl_percentage, type: "number", ddl_type: "DECIMAL(8,4)" } - { name: trades_executed, type: "number", ddl_type: "INTEGER" } - { name: winning_trades, type: "number", ddl_type: "INTEGER" } - { name: losing_trades, type: "number", ddl_type: "INTEGER" } - { name: win_rate, type: "number | null", ddl_type: "DECIMAL(5,2)" } - { name: max_drawdown, type: "number | null", ddl_type: "DECIMAL(5,2)" } - { name: sharpe_ratio, type: "number | null", ddl_type: "DECIMAL(5,2)" } - { name: signals_received, type: "number", ddl_type: "INTEGER" } - { name: signals_acted_on, type: "number", ddl_type: "INTEGER" } - { name: model_version, type: "string | null", ddl_type: "VARCHAR(50)" } - { name: strategy_config, type: "Record", ddl_type: "JSONB" } - { name: execution_log, type: "Record", ddl_type: "JSONB" } - { name: risk_metrics, type: "Record", ddl_type: "JSONB" } - { name: market_conditions, type: "Record | null", ddl_type: "JSONB" } - { name: status, type: "string", ddl_type: "VARCHAR(20)" } - { name: error_message, type: "string | null", ddl_type: "TEXT" } - { name: started_at, type: "Date", ddl_type: "TIMESTAMPTZ" } - { name: completed_at, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: created_at, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: AgentExecutionRow dto_names: - AgentExecutionFilters dependencies: ["TradingAgent (investment.types.ts)"] # -------------------------------------------------------------------------- # feature_flags.flags # -------------------------------------------------------------------------- - id: ENT-005 table: feature_flags.flags ddl_file: "apps/database/ddl/schemas/feature_flags/tables/01-flags.sql" target_file: "apps/backend/src/modules/feature-flags/types/feature-flags.types.ts" action: CREATE_FILE priority: P0 reason: "Service and controller exist but NO type definitions at all." interface_name: FeatureFlag columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: key, type: "string", ddl_type: "VARCHAR(100)" } - { name: name, type: "string", ddl_type: "VARCHAR(200)" } - { name: description, type: "string | null", ddl_type: "TEXT" } - { name: flagType, type: "string", ddl_type: "feature_flags.flag_type" } - { name: defaultValue, type: "unknown", ddl_type: "JSONB" } - { name: rules, type: "Record[]", ddl_type: "JSONB" } - { name: targetingPercentage, type: "number | null", ddl_type: "DECIMAL(5,2)" } - { name: isActive, type: "boolean", ddl_type: "BOOLEAN" } - { name: environment, type: "string", ddl_type: "VARCHAR(20)" } - { name: tags, type: "string[]", ddl_type: "TEXT[]" } - { name: createdBy, type: "string | null", ddl_type: "UUID" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } - { name: updatedAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: FeatureFlagRow dto_names: - CreateFeatureFlagInput - UpdateFeatureFlagInput dependencies: [] # -------------------------------------------------------------------------- # feature_flags.user_flags # -------------------------------------------------------------------------- - id: ENT-006 table: feature_flags.user_flags ddl_file: "apps/database/ddl/schemas/feature_flags/tables/01-flags.sql" target_file: "apps/backend/src/modules/feature-flags/types/feature-flags.types.ts" action: ADD_INTERFACE priority: P0 reason: "User-specific flag overrides. No type definitions." interface_name: UserFlag columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: userId, type: "string", ddl_type: "UUID" } - { name: flagId, type: "string", ddl_type: "UUID" } - { name: overrideValue, type: "unknown", ddl_type: "JSONB" } - { name: reason, type: "string | null", ddl_type: "TEXT" } - { name: expiresAt, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: UserFlagRow dependencies: ["FeatureFlag"] # -------------------------------------------------------------------------- # feature_flags.evaluations # -------------------------------------------------------------------------- - id: ENT-007 table: feature_flags.evaluations ddl_file: "apps/database/ddl/schemas/feature_flags/tables/01-flags.sql" target_file: "apps/backend/src/modules/feature-flags/types/feature-flags.types.ts" action: ADD_INTERFACE priority: P0 reason: "Flag evaluation history. No type definitions." interface_name: FlagEvaluation columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: flagId, type: "string", ddl_type: "UUID" } - { name: userId, type: "string | null", ddl_type: "UUID" } - { name: evaluatedValue, type: "unknown", ddl_type: "JSONB" } - { name: context, type: "Record | null", ddl_type: "JSONB" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: FlagEvaluationRow dependencies: ["FeatureFlag"] # -------------------------------------------------------------------------- # ml.risk_events # -------------------------------------------------------------------------- - id: ENT-008 table: ml.risk_events ddl_file: "apps/database/ddl/schemas/ml/tables/09-risk_events.sql" target_file: "apps/backend/src/modules/ml/types/ml.types.ts" action: ADD_INTERFACE priority: P0 reason: "Risk events table with no TypeScript interface." interface_name: RiskEvent columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: eventType, type: "string", ddl_type: "VARCHAR(50)" } - { name: symbol, type: "string | null", ddl_type: "VARCHAR(20)" } - { name: severity, type: "string", ddl_type: "VARCHAR(20)" } - { name: description, type: "string", ddl_type: "TEXT" } - { name: metadata, type: "Record", ddl_type: "JSONB" } - { name: resolvedAt, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: RiskEventRow dependencies: [] # -------------------------------------------------------------------------- # ml.llm_signals # -------------------------------------------------------------------------- - id: ENT-009 table: ml.llm_signals ddl_file: "apps/database/ddl/schemas/ml/tables/11-llm_signals.sql" target_file: "apps/backend/src/modules/ml/types/ml.types.ts" action: ADD_INTERFACE priority: P0 reason: "SERIAL PK table with no TypeScript interface." interface_name: LLMSignal columns: - { name: id, type: "number", ddl_type: "SERIAL" } - { name: symbol, type: "string", ddl_type: "VARCHAR(20)" } - { name: direction, type: "string", ddl_type: "VARCHAR(10)" } - { name: confidence, type: "number", ddl_type: "DECIMAL(5,4)" } - { name: reasoning, type: "string | null", ddl_type: "TEXT" } - { name: entryPrice, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: stopLoss, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: takeProfit, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } row_type_name: LLMSignalRow dependencies: [] # ============================================================================== # PHASE 2: HIGH - Missing Row Types for Active Tables (P1) # ============================================================================== # Tables that HAVE a TypeScript interface but are MISSING the Row type # (snake_case DB mapping interface). These are needed for type-safe SQL queries. # Estimated effort: 4-6 hours total # ============================================================================== phase_2_missing_row_types: title: "Create Missing Row Types for Active Tables" priority: P1 estimated_effort: "5 hours" total_items: 34 # -------------------------------------------------------------------------- # trading schema - 0 of 13 have Row types # -------------------------------------------------------------------------- trading_row_types: target_files: - "apps/backend/src/modules/trading/types/entity.types.ts" - "apps/backend/src/modules/trading/types/order.types.ts" - "apps/backend/src/modules/trading/types/drawing.types.ts" items: - { id: ROW-001, table: "trading.symbols", interface: Symbol, row_name: SymbolRow, target: "entity.types.ts" } - { id: ROW-002, table: "trading.watchlists", row_name: WatchlistRow, target: "entity.types.ts", needs_interface: true } - { id: ROW-003, table: "trading.watchlist_items", row_name: WatchlistItemRow, target: "entity.types.ts", needs_interface: true } - { id: ROW-004, table: "trading.bots", interface: TradingBot, row_name: TradingBotRow, target: "entity.types.ts" } - { id: ROW-005, table: "trading.orders", interface: Order, row_name: OrderRow, target: "order.types.ts" } - { id: ROW-006, table: "trading.positions", interface: "Position (NEW)", row_name: PositionRow, target: "order.types.ts" } - { id: ROW-007, table: "trading.trades", interface: "Trade (NEW)", row_name: TradeRow, target: "order.types.ts" } - { id: ROW-008, table: "trading.signals", interface: TradingSignal, row_name: TradingSignalRow, target: "entity.types.ts" } - { id: ROW-009, table: "trading.trading_metrics", interface: TradingMetrics, row_name: TradingMetricsRow, target: "entity.types.ts" } - { id: ROW-010, table: "trading.paper_balances", interface: PaperBalance, row_name: PaperBalanceRow, target: "entity.types.ts" } - { id: ROW-011, table: "trading.price_alerts", row_name: PriceAlertRow, target: "entity.types.ts", needs_interface: true } - { id: ROW-012, table: "trading.drawing_tools", interface: DrawingTool, row_name: DrawingToolRow, target: "drawing.types.ts" } - { id: ROW-013, table: "trading.drawing_templates", interface: DrawingTemplate, row_name: DrawingTemplateRow, target: "drawing.types.ts" } # -------------------------------------------------------------------------- # investment schema - 0 of 10 have Row types # -------------------------------------------------------------------------- investment_row_types: target_file: "apps/backend/src/modules/investment/types/investment.types.ts" items: - { id: ROW-014, table: "investment.products", row_name: ProductRow, needs_interface: true } - { id: ROW-015, table: "investment.risk_questionnaire", interface: RiskQuestionnaire, row_name: "EXISTS in risk.types.ts" } - { id: ROW-016, table: "investment.accounts", interface: InvestmentAccount, row_name: InvestmentAccountRow } - { id: ROW-017, table: "investment.distributions", interface: Distribution, row_name: DistributionRow } - { id: ROW-018, table: "investment.transactions", interface: InvestmentTransaction, row_name: InvestmentTransactionRow } - { id: ROW-019, table: "investment.withdrawal_requests", interface: WithdrawalRequest, row_name: "ALREADY snake_case" } - { id: ROW-020, table: "investment.daily_performance", interface: DailyPerformance, row_name: "ALREADY snake_case" } - { id: ROW-021, table: "investment.distribution_history", interface: DistributionHistory, row_name: "ALREADY snake_case" } - { id: ROW-022, table: "investment.distribution_runs", interface: "DistributionRun (NEW)", row_name: DistributionRunRow } - { id: ROW-023, table: "investment.agent_executions", interface: "AgentExecution (NEW)", row_name: AgentExecutionRow } # -------------------------------------------------------------------------- # audit schema - 0 of 7 have Row types # -------------------------------------------------------------------------- audit_row_types: target_file: "apps/backend/src/modules/audit/types/audit.types.ts" items: - { id: ROW-024, table: "audit.audit_logs", interface: AuditLog, row_name: AuditLogRow } - { id: ROW-025, table: "audit.security_events", interface: SecurityEvent, row_name: SecurityEventRow } - { id: ROW-026, table: "audit.system_events", interface: SystemEvent, row_name: SystemEventRow } - { id: ROW-027, table: "audit.trading_audit", interface: TradingAudit, row_name: TradingAuditRow } - { id: ROW-028, table: "audit.api_request_logs", interface: ApiRequestLog, row_name: ApiRequestLogRow } - { id: ROW-029, table: "audit.data_access_logs", interface: DataAccessLog, row_name: DataAccessLogRow } - { id: ROW-030, table: "audit.compliance_logs", interface: ComplianceLog, row_name: ComplianceLogRow } # -------------------------------------------------------------------------- # portfolio schema - 0 of 5 have Row types # -------------------------------------------------------------------------- portfolio_row_types: target_file: "apps/backend/src/modules/portfolio/types/portfolio.types.ts" items: - { id: ROW-031, table: "portfolio.portfolios", interface: Portfolio, row_name: PortfolioRow } - { id: ROW-032, table: "portfolio.portfolio_allocations", interface: PortfolioAllocation, row_name: PortfolioAllocationRow } - { id: ROW-033, table: "portfolio.portfolio_goals", interface: PortfolioGoal, row_name: PortfolioGoalRow } - { id: ROW-034, table: "portfolio.rebalance_history", interface: RebalanceHistory, row_name: RebalanceHistoryRow } # -------------------------------------------------------------------------- # Remaining partial schemas # -------------------------------------------------------------------------- remaining_row_types: items: - { id: ROW-035, table: "auth.oauth_accounts", interface: OAuthAccount, row_name: OAuthAccountRow, target: "auth.types.ts" } - { id: ROW-036, table: "auth.sessions", interface: Session, row_name: SessionRow, target: "auth.types.ts" } - { id: ROW-037, table: "education.courses", interface: Course, row_name: CourseRow, target: "education.types.ts" } - { id: ROW-038, table: "education.modules", interface: Module, row_name: ModuleRow, target: "education.types.ts" } - { id: ROW-039, table: "education.lessons", interface: Lesson, row_name: LessonRow, target: "education.types.ts" } - { id: ROW-040, table: "education.enrollments", interface: Enrollment, row_name: EnrollmentRow, target: "education.types.ts" } - { id: ROW-041, table: "education.quizzes", interface: Quiz, row_name: QuizRow, target: "education.types.ts" } - { id: ROW-042, table: "education.quiz_questions", interface: QuizQuestion, row_name: QuizQuestionRow, target: "education.types.ts" } - { id: ROW-043, table: "education.quiz_attempts", interface: QuizAttempt, row_name: QuizAttemptRow, target: "education.types.ts" } - { id: ROW-044, table: "education.certificates", interface: Certificate, row_name: CertificateRow, target: "education.types.ts" } - { id: ROW-045, table: "education.user_achievements", interface: UserAchievement, row_name: UserAchievementRow, target: "education.types.ts" } - { id: ROW-046, table: "education.user_gamification_profile", interface: UserGamificationProfile, row_name: UserGamificationProfileRow, target: "education.types.ts" } - { id: ROW-047, table: "education.user_activity_log", interface: UserActivityLog, row_name: UserActivityLogRow, target: "education.types.ts" } - { id: ROW-048, table: "education.course_tags", interface: CourseTag, row_name: CourseTagRow, target: "education.types.ts" } - { id: ROW-049, table: "education.course_tag_assignments", interface: CourseTagAssignment, row_name: CourseTagAssignmentRow, target: "education.types.ts" } - { id: ROW-050, table: "financial.subscriptions", interface: Subscription, row_name: SubscriptionRow, target: "financial.types.ts" } - { id: ROW-051, table: "financial.payments", interface: Payment, row_name: PaymentRow, target: "payments.types.ts or financial.types.ts" } - { id: ROW-052, table: "portfolio.portfolio_snapshots", interface: PortfolioSnapshot, row_name: PortfolioSnapshotRow, target: "portfolio.types.ts" } # ============================================================================== # PHASE 3: MEDIUM - Python-Managed ML Tables (P2) # ============================================================================== # These tables are primarily managed by the Python ML engine. # Read-only TypeScript interfaces needed for admin dashboards and monitoring. # Estimated effort: 1-2 hours # ============================================================================== phase_3_python_managed: title: "Create Read-Only Interfaces for Python-Managed Tables" priority: P2 estimated_effort: "2 hours" total_items: 4 items: - id: ML-001 table: ml.feature_store ddl_file: "apps/database/ddl/schemas/ml/tables/05-feature_store.sql" target_file: "apps/backend/src/modules/ml/types/ml.types.ts" action: ADD_INTERFACE interface_name: FeatureStoreEntry columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: symbol, type: "string", ddl_type: "VARCHAR(20)" } - { name: timeframe, type: "string", ddl_type: "VARCHAR(10)" } - { name: featureName, type: "string", ddl_type: "VARCHAR(100)" } - { name: featureValue, type: "number", ddl_type: "DECIMAL(18,8)" } - { name: featureType, type: "string", ddl_type: "VARCHAR(50)" } - { name: computedAt, type: "Date", ddl_type: "TIMESTAMPTZ" } - { name: dataVersion, type: "string | null", ddl_type: "VARCHAR(50)" } - { name: metadata, type: "Record", ddl_type: "JSONB" } - { name: isLatest, type: "boolean", ddl_type: "BOOLEAN" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } notes: "Read-only from Express backend perspective." - id: ML-002 table: ml.llm_predictions ddl_file: "apps/database/ddl/schemas/ml/tables/06-llm_predictions.sql" target_file: "apps/backend/src/modules/ml/types/ml.types.ts" action: ADD_INTERFACE interface_name: LLMPrediction columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: symbol, type: "string", ddl_type: "VARCHAR(20)" } - { name: timeframe, type: "string", ddl_type: "VARCHAR(10)" } - { name: direction, type: "string", ddl_type: "VARCHAR(10)" } - { name: confidence, type: "number", ddl_type: "DECIMAL(5,4)" } - { name: reasoning, type: "string | null", ddl_type: "TEXT" } - { name: entryPrice, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: stopLoss, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: takeProfit, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: modelName, type: "string | null", ddl_type: "VARCHAR(100)" } - { name: promptTokens, type: "number | null", ddl_type: "INTEGER" } - { name: completionTokens, type: "number | null", ddl_type: "INTEGER" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } notes: "Read-only from Express backend. Written by Python LLM service." - id: ML-003 table: ml.llm_prediction_outcomes ddl_file: "apps/database/ddl/schemas/ml/tables/07-llm_prediction_outcomes.sql" target_file: "apps/backend/src/modules/ml/types/ml.types.ts" action: ADD_INTERFACE interface_name: LLMPredictionOutcome columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: predictionId, type: "string", ddl_type: "UUID" } - { name: actualDirection, type: "string | null", ddl_type: "VARCHAR(10)" } - { name: actualPrice, type: "number | null", ddl_type: "DECIMAL(18,8)" } - { name: hitTarget, type: "boolean | null", ddl_type: "BOOLEAN" } - { name: hitStop, type: "boolean | null", ddl_type: "BOOLEAN" } - { name: pnlPercent, type: "number | null", ddl_type: "DECIMAL(8,4)" } - { name: outcomeStatus, type: "string", ddl_type: "VARCHAR(20)" } - { name: verifiedAt, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: notes, type: "string | null", ddl_type: "TEXT" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } notes: "Tracks outcome verification for LLM predictions." - id: ML-004 table: ml.llm_decisions ddl_file: "apps/database/ddl/schemas/ml/tables/08-llm_decisions.sql" target_file: "apps/backend/src/modules/ml/types/ml.types.ts" action: ADD_INTERFACE interface_name: LLMDecision columns: - { name: id, type: "string", ddl_type: "UUID" } - { name: predictionId, type: "string | null", ddl_type: "UUID" } - { name: decisionType, type: "string", ddl_type: "VARCHAR(50)" } - { name: action, type: "string", ddl_type: "VARCHAR(50)" } - { name: reasoning, type: "string | null", ddl_type: "TEXT" } - { name: confidence, type: "number | null", ddl_type: "DECIMAL(5,4)" } - { name: parameters, type: "Record | null", ddl_type: "JSONB" } - { name: executed, type: "boolean", ddl_type: "BOOLEAN" } - { name: executedAt, type: "Date | null", ddl_type: "TIMESTAMPTZ" } - { name: createdAt, type: "Date", ddl_type: "TIMESTAMPTZ" } notes: "Decision log for LLM-driven actions." # ============================================================================== # PHASE 4: OPTIONAL - Repository Expansion (P3) # ============================================================================== # Currently only 9 repositories exist (investment: 5, portfolio: 3, risk: 1). # This phase recommends creating repositories for high-traffic tables. # ============================================================================== phase_4_repositories: title: "Expand Repository Pattern to Key Modules" priority: P3 estimated_effort: "8-12 hours" notes: "Optional. Only create repositories where complex queries exist." recommended_modules: - module: auth reason: "Most complex schema. Multiple services share SQL for users, sessions, tokens." recommended_repos: - { name: "user.repository.ts", tables: ["auth.users", "auth.user_profiles"] } - { name: "session.repository.ts", tables: ["auth.sessions", "auth.auth_logs", "auth.login_attempts"] } - { name: "verification.repository.ts", tables: ["auth.email_verifications", "auth.phone_verifications", "auth.password_reset_tokens"] } - module: trading reason: "Core business domain. Order/position/trade queries are complex." recommended_repos: - { name: "order.repository.ts", tables: ["trading.orders", "trading.trades", "trading.positions"] } - { name: "symbol.repository.ts", tables: ["trading.symbols"] } - { name: "watchlist.repository.ts", tables: ["trading.watchlists", "trading.watchlist_items"] } - module: education reason: "Largest schema (19 tables). Complex enrollment/progress queries." recommended_repos: - { name: "course.repository.ts", tables: ["education.courses", "education.modules", "education.lessons", "education.categories"] } - { name: "enrollment.repository.ts", tables: ["education.enrollments", "education.progress"] } - { name: "quiz.repository.ts", tables: ["education.quizzes", "education.quiz_questions", "education.quiz_attempts"] } - module: financial reason: "Financial data requires strict transaction handling." recommended_repos: - { name: "wallet.repository.ts", tables: ["financial.wallets", "financial.wallet_transactions", "financial.wallet_audit_log", "financial.wallet_limits"] } - { name: "payment.repository.ts", tables: ["financial.payments", "financial.refunds", "financial.invoices"] } # ============================================================================== # EXECUTION SUMMARY # ============================================================================== execution_summary: total_work_items: 65 breakdown: phase_1_interfaces: 9 phase_2_row_types: 52 phase_3_ml_interfaces: 4 phase_4_repositories: "Optional (11 repos recommended)" estimated_total_effort: "10-13 hours (excluding Phase 4)" recommended_order: 1: "Phase 1 - ENT-001 to ENT-009 (missing interfaces for active tables)" 2: "Phase 2 - Trading Row types (ROW-001 to ROW-013)" 3: "Phase 2 - Investment Row types (ROW-014 to ROW-023)" 4: "Phase 2 - Audit Row types (ROW-024 to ROW-030)" 5: "Phase 2 - Portfolio Row types (ROW-031 to ROW-034)" 6: "Phase 2 - Remaining Row types (ROW-035 to ROW-052)" 7: "Phase 3 - ML read-only interfaces (ML-001 to ML-004)" 8: "Phase 4 - Repository expansion (only if needed)" validation_steps: - "After each phase: npm run build (verify TypeScript compilation)" - "After each phase: npm run lint (verify code style)" - "After Phase 1: Verify all 101 tables have at least one TypeScript interface" - "After Phase 2: Verify Row types match DDL column names exactly" - "Cross-reference: Every Row type field must match a DDL column" blocking_dependencies: - "ENT-002 (Position) must be created before ROW-006" - "ENT-001 (Trade) must be created before ROW-007" - "ENT-005 (FeatureFlag) file must be created before ENT-006 and ENT-007" - "ENT-003 (DistributionRun) must be created before ROW-022" - "ENT-004 (AgentExecution) must be created before ROW-023"