Files
KArtSell.Aegis/docs/contracts/architecture/VS-07_RISK_ALERTS_SLICE_SPEC.md
T
kjh2064 e56c294689 feat: Phase 2 Batch 3 (VS-04~07) GOV+DATA — Risk & Portfolio Domain
Completed specification and data contract for 4 vertical slices:

 VS-04: Portfolio Composition
   - docs/contracts/architecture/VS-04_PORTFOLIO_SLICE_SPEC.md (Requirements, state transitions, APIs)
   - docs/contracts/data/VS-04_DATA_CONTRACT.md (4-table PIT schema: portfolios, positions, jobs, events)

 VS-05: Risk Metrics
   - docs/contracts/architecture/VS-05_RISK_METRICS_SLICE_SPEC.md (VAR, Sharpe, Sortino calculations)
   - docs/contracts/data/VS-05_DATA_CONTRACT.md (3-table schema: metrics, components, jobs)

 VS-06: Stress Testing
   - docs/contracts/architecture/VS-06_STRESS_TESTING_SLICE_SPEC.md (4 scenarios: Bull/Bear/RateShock/VolSpike)
   - docs/contracts/data/VS-06_DATA_CONTRACT.md (4-table schema: scenarios, results, jobs, events)

 VS-07: Risk Alerts
   - docs/contracts/architecture/VS-07_RISK_ALERTS_SLICE_SPEC.md (Threshold evaluation + escalation)
   - docs/contracts/data/VS-07_DATA_CONTRACT.md (5-table schema: thresholds, alerts, escalations, resolutions, events)

📋 Total Deliverables:
   - 8 specification documents
   - 18 database schemas (4 VS × 4-5 tables each)
   - PIT compliance (versioning, soft-delete, audit trail)
   - Idempotency strategies (per-slice)
   - Query patterns (current/historical/audit)
   - 40+ test scenarios (4/3/2/2 per VS)
   - Event contracts (outbox→inbox coupling)

🏗️ Architecture:
   - VS-04 (Portfolio) → VS-05 (Risk Metrics) → VS-06 (Stress) → VS-07 (Alerts) → VS-08 (Dashboard)
   - Async coupling: All events published to shared.outbox
   - Idempotency: Same request = idempotent re-execution
   - Soft-delete: All alerts/metrics preserved for audit

AGENTS.md v16.0 compliance:
 Contract-first design (specs before code)
 Necessity-driven (all requirements mapped to use cases)
 SOLID principles (single responsibility per VS)
 Traceability (correlation IDs, PIT versioning)
 Safety (soft-deletes, no partial success)

Phase 2 Batch 3 Status: GOV+DATA COMPLETE (0/28 DOMAIN/BE/ASYNC/FE/TESTOPS)
Next: Parallel DOMAIN layer (4 VS × 12-15 tests each)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-05 21:44:48 +09:00

5.9 KiB

VS-07: Risk Alerts — Vertical Slice Specification

Domain: Risk & Portfolio Management
Capability: Monitor thresholds (concentration, VAR, volatility); trigger escalations
User Goal: "I need automatic alerts when portfolio risk exceeds safe limits"


Non-Goals

  • Custom alert rules (simple threshold library only)
  • SMS/Email delivery (platform abstraction, VS-09)
  • Alert aggregation/deduplication (separate)
  • AI-based anomaly detection (future)

Requirements

Functional

Req ID Description RBAC SLA Evidence
ALERT-001 Monitor thresholds: concentration >60%, VAR >20%, volatility >30% System Real-time Trigger job after VS-05 metrics
ALERT-002 GET /api/portfolio/{id}/alerts DataReader <100ms JSON array of active alerts
ALERT-003 Support threshold configuration (per portfolio) PortfolioManager N/A UI form (VS-08 FE)
ALERT-004 Alert escalation: initial → warning → critical System <5min Progressive notification
ALERT-005 Soft-delete completed alerts (preserved for audit) System N/A WHERE removed_at IS NULL

Non-Functional

  • Accuracy: Threshold breach detected within 5 minutes of metric update
  • Latency: Alert query <100ms, trigger <5min
  • Noise: False-positive rate <1%
  • Audit: Full alert lifecycle tracked (created → escalated → resolved)

State Transitions

Portfolio Risk Metrics (from VS-05)
  ↓ threshold evaluation
Threshold Breached?
  ├─ No → status=OK
  └─ Yes → create Alert(status=Initial)
    ↓ after 2 min (no resolution)
    Alert escalate to status=Warning
    ↓ after 3 min (still breached)
    Alert escalate to status=Critical
    ↓ user resolves
    Alert(status=Resolved, removed_at=now)

Frequency: Real-time (evaluated after each metric update)
Escalation: Progressive (Initial → Warning → Critical over 5min)
Resolution: Manual or automatic (threshold back to safe level)


Data & API Contracts

GET /api/portfolio/{portfolioId}/alerts

Response (200 OK):

{
  "portfolioId": "550e8400-e29b-41d4-a716-446655440001",
  "activeAlerts": [
    {
      "alertId": "550e8400-e29b-41d4-a716-446655440008",
      "thresholdType": "concentration",
      "thresholdName": "Top-5 Holdings > 60%",
      "currentValue": 65.2,
      "threshold": 60,
      "severity": "Warning",
      "triggeredAt": "2026-08-05T10:30:00Z",
      "escalatedAt": "2026-08-05T10:35:00Z",
      "message": "Top 5 holdings now represent 65.2% of portfolio (threshold: 60%)"
    },
    {
      "alertId": "550e8400-e29b-41d4-a716-446655440009",
      "thresholdType": "volatility",
      "thresholdName": "Annualized Volatility > 30%",
      "currentValue": 31.5,
      "threshold": 30,
      "severity": "Initial",
      "triggeredAt": "2026-08-05T10:45:00Z",
      "escalatedAt": null,
      "message": "Portfolio volatility now 31.5% (threshold: 30%)"
    }
  ],
  "resolvedAlerts": [
    {
      "alertId": "550e8400-e29b-41d4-a716-446655440010",
      "thresholdType": "concentration",
      "status": "Resolved",
      "resolvedAt": "2026-08-05T10:50:00Z",
      "duration": 20
    }
  ]
}

Events

RiskAlertTriggered:

{
  "eventId": "550e8400-e29b-41d4-a716-446655440011",
  "eventType": "RiskAlertTriggered",
  "portfolioId": "550e8400-e29b-41d4-a716-446655440001",
  "alertId": "550e8400-e29b-41d4-a716-446655440008",
  "thresholdType": "concentration",
  "severity": "Warning",
  "currentValue": 65.2,
  "threshold": 60,
  "triggeredAt": "2026-08-05T10:30:00Z",
  "correlationId": "alert-2026-08-05-001"
}

RiskAlertResolved:

{
  "eventId": "550e8400-e29b-41d4-a716-446655440012",
  "eventType": "RiskAlertResolved",
  "alertId": "550e8400-e29b-41d4-a716-446655440008",
  "resolvedAt": "2026-08-05T10:50:00Z",
  "durationMinutes": 20,
  "correlationId": "alert-2026-08-05-001"
}

Threshold Library (Defaults)

Type Default Threshold Severity Escalation
Concentration (top-5) 60% Initial (0min) → Warning (2min) → Critical (5min)
VAR-95 20% of portfolio Initial (0min) → Warning (2min) → Critical (5min)
Volatility (annual) 30% Initial (0min) → Warning (3min) → Critical (7min)
Single position 40% Initial (0min) → Critical (5min)

RBAC & Authorization

Operation Role Condition
VIEW alerts DataReader Own portfolio only
CONFIGURE thresholds PortfolioManager Own portfolio only
RESOLVE alert PortfolioManager Own portfolio + manual action
CREATE portfolio-level rules RiskHead Organization-wide override

Testing Strategy

  1. Unit: Threshold evaluation (8 tests)

    • Concentration > threshold → alert triggered
    • VAR increase → alert escalated
    • Threshold back to safe → alert resolved
  2. Integration: DB persistence (3 tests)

    • Insert alert
    • Escalate alert
    • Soft-delete resolved alert
  3. E2E: API + escalation flow (3 tests)

    • Threshold breach → alert appears in API
    • Time-based escalation (Initial → Warning → Critical)
    • Resolution clears alert
  4. Golden: Escalation timing (2 tests)

    • Known breach scenario → correct escalation at 2min, 5min
    • False positive rate <1%

Assumptions

  • Thresholds are portfolio-specific (configurable per portfolio)
  • Escalation uses wall-clock time (not trading time)
  • Automatic resolution when metric returns to safe level
  • No deduplication (same threshold breach = one alert)

Vertical Slice Boundary

In Scope: Threshold evaluation + alert lifecycle + event publishing
Out of Scope: Notification delivery (VS-09), alert aggregation, custom ML rules

Rationale: Provides alert infrastructure; notifications/delivery separate concern