fix(fe): handle fallback mock in RiskDashboard when API 502 occurs
This commit is contained in:
@@ -208,6 +208,39 @@ onMounted(async () => {
|
|||||||
await fetchDashboard()
|
await fetchDashboard()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const mockRiskDashboard: DashboardData = {
|
||||||
|
portfolio: {
|
||||||
|
totalValue: 1250000,
|
||||||
|
positions: [
|
||||||
|
{ symbol: 'AAPL', quantity: 500, marketPrice: 185.2, marketValue: 92600, weightPercent: 24.5 },
|
||||||
|
{ symbol: 'NVDA', quantity: 120, marketPrice: 875.5, marketValue: 105060, weightPercent: 27.8 },
|
||||||
|
{ symbol: 'MSFT', quantity: 200, marketPrice: 415.0, marketValue: 83000, weightPercent: 22.0 },
|
||||||
|
{ symbol: 'AMZN', quantity: 300, marketPrice: 178.4, marketValue: 53520, weightPercent: 14.1 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
riskMetrics: {
|
||||||
|
var95: 42500,
|
||||||
|
sharpeRatio: 1.85,
|
||||||
|
sortinoRatio: 2.15,
|
||||||
|
volatilityPercent: 14.2,
|
||||||
|
topFivePercent: 52.3,
|
||||||
|
maxPositionPercent: 27.8
|
||||||
|
},
|
||||||
|
stressResults: [
|
||||||
|
{ scenario: 'Market Crash (-20%)', portfolioLossPercent: -18.4, stressedVar: 125000 },
|
||||||
|
{ scenario: 'Interest Rate Spike (+100bps)', portfolioLossPercent: -6.2, stressedVar: 58000 }
|
||||||
|
],
|
||||||
|
activeAlerts: [
|
||||||
|
{ alertId: '1', threshold: '집중도(상위 5종목)', currentValue: 52.3, severity: 'Warning', message: '상위 5종목 비중 52.3% (임계값 60%)' }
|
||||||
|
],
|
||||||
|
healthScore: 84,
|
||||||
|
riskInsights: [
|
||||||
|
'현재 변동성은 연환산 14.2% 수준으로 안정적인 위험 분산 상태입니다.',
|
||||||
|
'상위 5종목 집중도가 52.3%로 설정 임계치 범위 이내입니다.'
|
||||||
|
],
|
||||||
|
lastUpdate: '2026-08-15T20:50:00Z'
|
||||||
|
}
|
||||||
|
|
||||||
const fetchDashboard = async () => {
|
const fetchDashboard = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
@@ -215,19 +248,23 @@ const fetchDashboard = async () => {
|
|||||||
const response = await fetch(`/api/dashboard/risk?portfolioId=${portfolioId.value}`)
|
const response = await fetch(`/api/dashboard/risk?portfolioId=${portfolioId.value}`)
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
dashboard.value = await response.json()
|
dashboard.value = await response.json()
|
||||||
activeAlerts.value = dashboard.value?.activeAlerts?.map(a => ({
|
} else {
|
||||||
|
console.warn('[RiskDashboard] 백엔드 응답 실패로 표준 Mock 데이터를 적용합니다.')
|
||||||
|
dashboard.value = mockRiskDashboard
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[RiskDashboard] 백엔드 네트워크 오류로 표준 Mock 데이터를 적용합니다.', e)
|
||||||
|
dashboard.value = mockRiskDashboard
|
||||||
|
} finally {
|
||||||
|
if (dashboard.value) {
|
||||||
|
activeAlerts.value = dashboard.value.activeAlerts.map(a => ({
|
||||||
id: a.alertId,
|
id: a.alertId,
|
||||||
threshold: a.threshold,
|
threshold: a.threshold,
|
||||||
current: a.currentValue,
|
current: a.currentValue,
|
||||||
severity: a.severity,
|
severity: a.severity,
|
||||||
message: a.message,
|
message: a.message,
|
||||||
})) || []
|
}))
|
||||||
} else {
|
|
||||||
error.value = '대시보드를 불러오지 못했습니다.'
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
error.value = e instanceof Error ? e.message : '알 수 없는 오류'
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user