2eee44d19b
- VS-08_DASHBOARD_SLICE_SPEC.md: Comprehensive dashboard specification - VS-08_DATA_CONTRACT.md: PIT aggregation schema + caching strategy - VS08_DashboardPolicy.cs: Aggregation logic (health score, insights, validation) - VS08_DashboardEndpoint.cs: GET /api/dashboard/risk + cache layer - RiskDashboard.vue: Unified portfolio view with real-time metrics - VS08_DashboardIntegrationTests.cs: 5 core policy tests Status: GOV+DATA+DOMAIN+BE+ASYNC+FE complete (5/7 vertical slices) TESTOPS: In progress (test suite has minor compatibility issues with VS-04/07) Cumulative: Phase 2 Batch 3 + Phase 3 = 27/36 components (75% COMPLETE) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
153 lines
3.6 KiB
Markdown
153 lines
3.6 KiB
Markdown
# VS-08: Risk Dashboard — Vertical Slice Specification
|
|
|
|
**Domain:** Comprehensive Risk Monitoring
|
|
**Capability:** Real-time aggregation of portfolio, risk metrics, stress scenarios, and alerts
|
|
**User Goal:** "I need a unified view of my entire portfolio risk profile in one dashboard"
|
|
|
|
---
|
|
|
|
## Non-Goals
|
|
|
|
- Custom dashboard builder (fixed layout)
|
|
- Real-time market tick updates (EOD refresh acceptable)
|
|
- Mobile-optimized view (desktop focus)
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
### Functional
|
|
|
|
| Req ID | Description | RBAC | SLA | Evidence |
|
|
|--------|-------------|------|-----|----------|
|
|
| **DASH-001** | GET /api/dashboard/risk | DataReader | <500ms | Aggregated JSON |
|
|
| **DASH-002** | Render portfolio composition (VS-04) | System | <100ms FE | Visual table |
|
|
| **DASH-003** | Display risk metrics (VS-05) | System | <100ms FE | Metric cards |
|
|
| **DASH-004** | Show stress scenarios (VS-06) | System | <100ms FE | Scenario grid |
|
|
| **DASH-005** | List active alerts (VS-07) | System | <100ms FE | Alert badges |
|
|
| **DASH-006** | Real-time updates via SignalR | System | <5s latency | WebSocket push |
|
|
|
|
### Non-Functional
|
|
|
|
- **Availability:** 99.5%
|
|
- **Latency:** <500ms aggregation, <100ms FE render
|
|
- **Caching:** Cache dashboard for <1hr (refresh on alert escalation)
|
|
- **Audit:** All data sourced from authoritative VS-04~07 tables
|
|
|
|
---
|
|
|
|
## State Transitions
|
|
|
|
```
|
|
Portfolio Snapshot (VS-04)
|
|
Risk Metrics (VS-05)
|
|
Stress Results (VS-06)
|
|
Risk Alerts (VS-07)
|
|
↓ (All aggregated)
|
|
Dashboard Data (VS-08)
|
|
↓ (Publish event)
|
|
DashboardUpdated event → SignalR push
|
|
```
|
|
|
|
**Frequency:** On-demand + event-driven updates
|
|
**Real-time:** SignalR WebSocket (no polling)
|
|
|
|
---
|
|
|
|
## Data & API Contracts
|
|
|
|
### GET /api/dashboard/risk
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"portfolioId": "550e8400-e29b-41d4-a716-446655440001",
|
|
"snapshotDate": "2026-08-05",
|
|
"portfolio": {
|
|
"totalValue": 42700.00,
|
|
"positions": [
|
|
{
|
|
"symbol": "AAPL",
|
|
"quantity": 100,
|
|
"marketValue": 15025,
|
|
"weightPercent": 35.3
|
|
}
|
|
]
|
|
},
|
|
"riskMetrics": {
|
|
"var95": 15250,
|
|
"sharpe": 1.85,
|
|
"sortino": 2.45,
|
|
"volatility": 0.185,
|
|
"concentration": {
|
|
"topFivePercent": 52.3,
|
|
"maxPosition": 40.0
|
|
}
|
|
},
|
|
"stressResults": [
|
|
{
|
|
"scenario": "bull",
|
|
"portfolioLoss": 12500,
|
|
"lossPercent": 4.2,
|
|
"stressedVar": 13750
|
|
}
|
|
],
|
|
"activeAlerts": [
|
|
{
|
|
"alertId": "550e8400-e29b-41d4-a716-446655440008",
|
|
"threshold": "Concentration",
|
|
"severity": "Warning",
|
|
"message": "Top 5 holdings at 52.3%"
|
|
}
|
|
],
|
|
"lastUpdate": "2026-08-05T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
### SignalR Message
|
|
|
|
**DashboardUpdated:**
|
|
```json
|
|
{
|
|
"eventType": "DashboardUpdated",
|
|
"portfolioId": "550e8400-e29b-41d4-a716-446655440001",
|
|
"changedComponents": ["riskMetrics", "activeAlerts"],
|
|
"updatedAt": "2026-08-05T10:05:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## RBAC & Authorization
|
|
|
|
| Operation | Role | Condition |
|
|
|-----------|------|-----------|
|
|
| VIEW dashboard | DataReader | Own portfolio only |
|
|
| TRIGGER refresh | DataAnalyst | Manual override |
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
1. **Unit:** Data aggregation logic (5 tests)
|
|
2. **Integration:** DB → aggregation → API (4 tests)
|
|
3. **E2E:** Full dashboard load + SignalR push (2 tests)
|
|
4. **Golden:** Known portfolio → expected snapshot
|
|
|
|
---
|
|
|
|
## Assumptions
|
|
|
|
- All VS-04~07 data is fresh (<1hr old)
|
|
- SignalR hub is available (separate deployment)
|
|
- Portfolio ID is authenticated via RBAC
|
|
|
|
---
|
|
|
|
## Vertical Slice Boundary
|
|
|
|
✅ **In Scope:** Aggregation logic + API endpoint + real-time updates
|
|
❌ **Out of Scope:** Custom drill-down reports, export functionality
|
|
|
|
**Rationale:** Minimal, read-only aggregation; all mutations in VS-04~07
|