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>
590 lines
34 KiB
YAML
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"
|