diff --git a/src/modules/portfolio/controllers/portfolio.controller.ts b/src/modules/portfolio/controllers/portfolio.controller.ts index 963d25b..edff638 100644 --- a/src/modules/portfolio/controllers/portfolio.controller.ts +++ b/src/modules/portfolio/controllers/portfolio.controller.ts @@ -4,8 +4,9 @@ */ import { Request, Response, NextFunction } from 'express'; -import { portfolioService, RiskProfile } from '../services/portfolio.service'; +import { portfolioService } from '../services/portfolio.service'; import { snapshotRepository } from '../repositories/snapshot.repository'; +import type { RiskProfile } from '../types/portfolio.types'; // ============================================================================ // Types diff --git a/src/modules/portfolio/repositories/goal.repository.ts b/src/modules/portfolio/repositories/goal.repository.ts index 9c1f12d..f05482b 100644 --- a/src/modules/portfolio/repositories/goal.repository.ts +++ b/src/modules/portfolio/repositories/goal.repository.ts @@ -4,13 +4,12 @@ */ import { db } from '../../../shared/database'; +import type { GoalStatus, PortfolioGoal } from '../types/portfolio.types'; // ============================================================================ -// Types +// Database Row Types (snake_case from DB) // ============================================================================ -export type GoalStatus = 'active' | 'completed' | 'abandoned'; - export interface GoalRow { id: string; user_id: string; @@ -31,25 +30,7 @@ export interface GoalRow { updated_at: Date; } -export interface PortfolioGoal { - id: string; - userId: string; - portfolioId: string | null; - name: string; - description: string | null; - targetAmount: number; - currentAmount: number; - targetDate: Date; - monthlyContribution: number; - progress: number; - projectedCompletionDate: Date | null; - monthsRemaining: number | null; - requiredMonthlyContribution: number | null; - status: GoalStatus; - completedAt: Date | null; - createdAt: Date; - updatedAt: Date; -} +// PortfolioGoal interface imported from types/portfolio.types.ts export interface CreateGoalInput { userId: string; diff --git a/src/modules/portfolio/repositories/portfolio.repository.ts b/src/modules/portfolio/repositories/portfolio.repository.ts index 478f5c2..006ea23 100644 --- a/src/modules/portfolio/repositories/portfolio.repository.ts +++ b/src/modules/portfolio/repositories/portfolio.repository.ts @@ -4,14 +4,17 @@ */ import { db } from '../../../shared/database'; +import type { + RiskProfile, + AllocationStatus, + Portfolio, + PortfolioAllocation, +} from '../types/portfolio.types'; // ============================================================================ -// Types +// Database Row Types (snake_case from DB) // ============================================================================ -export type RiskProfile = 'conservative' | 'moderate' | 'aggressive'; -export type AllocationStatus = 'active' | 'inactive' | 'rebalancing'; - export interface PortfolioRow { id: string; user_id: string; @@ -33,26 +36,7 @@ export interface PortfolioRow { updated_at: Date; } -export interface Portfolio { - id: string; - userId: string; - name: string; - description: string | null; - riskProfile: RiskProfile; - totalValue: number; - totalCost: number; - unrealizedPnl: number; - unrealizedPnlPercent: number; - dayChangePercent: number; - weekChangePercent: number; - monthChangePercent: number; - allTimeChangePercent: number; - isActive: boolean; - isPrimary: boolean; - lastRebalancedAt: Date | null; - createdAt: Date; - updatedAt: Date; -} +// Portfolio interface imported from types/portfolio.types.ts export interface AllocationRow { id: string; @@ -73,24 +57,7 @@ export interface AllocationRow { created_at: Date; } -export interface PortfolioAllocation { - id: string; - portfolioId: string; - asset: string; - targetPercent: number; - currentPercent: number; - deviation: number; - quantity: number; - avgCost: number; - currentPrice: number; - value: number; - cost: number; - pnl: number; - pnlPercent: number; - status: AllocationStatus; - lastUpdatedAt: Date; - createdAt: Date; -} +// PortfolioAllocation interface imported from types/portfolio.types.ts export interface CreatePortfolioInput { userId: string; diff --git a/src/modules/portfolio/repositories/snapshot.repository.ts b/src/modules/portfolio/repositories/snapshot.repository.ts index 73d7ca9..2bdb1db 100644 --- a/src/modules/portfolio/repositories/snapshot.repository.ts +++ b/src/modules/portfolio/repositories/snapshot.repository.ts @@ -4,9 +4,10 @@ */ import { db } from '../../../shared/database'; +import type { PortfolioSnapshot, PerformanceDataPoint } from '../types/portfolio.types'; // ============================================================================ -// Types +// Database Row Types (snake_case from DB) // ============================================================================ export interface SnapshotRow { @@ -23,19 +24,7 @@ export interface SnapshotRow { created_at: Date; } -export interface PortfolioSnapshot { - id: string; - portfolioId: string; - snapshotDate: Date; - totalValue: number; - totalCost: number; - unrealizedPnl: number; - unrealizedPnlPercent: number; - dayChange: number; - dayChangePercent: number; - allocations: Record | null; - createdAt: Date; -} +// PortfolioSnapshot interface imported from types/portfolio.types.ts export interface CreateSnapshotInput { portfolioId: string; @@ -49,14 +38,7 @@ export interface CreateSnapshotInput { allocations?: Record; } -export interface PerformanceDataPoint { - date: string; - value: number; - pnl: number; - pnlPercent: number; - change: number; - changePercent: number; -} +// PerformanceDataPoint interface imported from types/portfolio.types.ts // ============================================================================ // Helper Functions diff --git a/src/modules/portfolio/services/portfolio.service.ts b/src/modules/portfolio/services/portfolio.service.ts index 198d57b..042ad6b 100644 --- a/src/modules/portfolio/services/portfolio.service.ts +++ b/src/modules/portfolio/services/portfolio.service.ts @@ -7,23 +7,19 @@ import { v4 as uuidv4 } from 'uuid'; import { marketService } from '../../trading/services/market.service'; -import { - portfolioRepository, - Portfolio as RepoPortfolio, - PortfolioAllocation as RepoAllocation, - RiskProfile as RepoRiskProfile, -} from '../repositories/portfolio.repository'; -import { - goalRepository, - PortfolioGoal as RepoGoal, -} from '../repositories/goal.repository'; +import { portfolioRepository } from '../repositories/portfolio.repository'; +import { goalRepository } from '../repositories/goal.repository'; +import type { + Portfolio as DBPortfolio, + PortfolioAllocation as DBAllocation, + PortfolioGoal as DBGoal, + RiskProfile, +} from '../types/portfolio.types'; // ============================================================================ -// Types +// Service DTOs (with computed/additional fields) // ============================================================================ -export type RiskProfile = 'conservative' | 'moderate' | 'aggressive'; - export interface Portfolio { id: string; userId: string; @@ -125,8 +121,8 @@ const DEFAULT_ALLOCATIONS: Record | null; + createdAt: Date; +} + +// ============================================================================ +// Input/Output DTOs +// ============================================================================ + +export interface CreatePortfolioInput { + userId: string; + name: string; + description?: string; + riskProfile: RiskProfile; +} + +export interface UpdatePortfolioInput { + name?: string; + description?: string; + riskProfile?: RiskProfile; + isActive?: boolean; + isPrimary?: boolean; +} + +export interface CreateAllocationInput { + portfolioId: string; + asset: string; + targetPercent: number; + quantity?: number; + avgCost?: number; +} + +export interface UpdateAllocationInput { + targetPercent?: number; + quantity?: number; + avgCost?: number; + status?: AllocationStatus; +} + +export interface CreateGoalInput { + userId: string; + portfolioId?: string; + name: string; + description?: string; + targetAmount: number; + targetDate: Date; + monthlyContribution?: number; +} + +export interface UpdateGoalInput { + name?: string; + description?: string; + targetAmount?: number; + targetDate?: Date; + monthlyContribution?: number; + currentAmount?: number; + status?: GoalStatus; +} + +export interface RebalanceRecommendation { + asset: string; + action: RebalanceAction; + currentPercent: number; + targetPercent: number; + deviation: number; + quantityChange: number; + valueChange: number; + priority: number; +} + +export interface PerformanceDataPoint { + date: string; + value: number; + pnl: number; + pnlPercent: number; + change: number; + changePercent: number; +} + +export interface PortfolioSummary { + portfolio: Portfolio; + allocations: PortfolioAllocation[]; + totalAllocated: number; + unallocatedPercent: number; + needsRebalance: boolean; + lastSnapshot: PortfolioSnapshot | null; +}