trading-platform/orchestration/tareas/TASK-2026-02-05-ANALISIS-VALIDACION-MODELADO-BD/entregables/ENTITIES-CREATION-PLAN.yml
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

590 lines
34 KiB
YAML

# ==============================================================================
# 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<string, unknown>", ddl_type: "JSONB" }
- { name: execution_log, type: "Record<string, unknown>", ddl_type: "JSONB" }
- { name: risk_metrics, type: "Record<string, unknown>", ddl_type: "JSONB" }
- { name: market_conditions, type: "Record<string, unknown> | 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<string, unknown>[]", 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<string, unknown> | 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<string, unknown>", 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<string, unknown>", 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<string, unknown> | 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"