Files
PROJECT-CONTORL/openspec/changes/archive/2026-01-07-add-dashboard-widgets/design.md
beabigegg 4860704543 feat: implement dashboard widgets functionality
Backend:
- Add dashboard API router with widget endpoints
- Create dashboard schemas for widget data
- Add dashboard tests

Frontend:
- Enhance Dashboard page with widget components
- Add dashboard service for API calls
- Create reusable dashboard components

OpenSpec:
- Archive add-dashboard-widgets change
- Add dashboard capability specs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 22:52:28 +08:00

4.8 KiB

Design: Dashboard Widgets

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                    Dashboard Page                            │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│  │ My Tasks    │ │ Due This    │ │ Overdue     │ │ Done % │ │
│  │ 12          │ │ Week: 5     │ │ 2           │ │ 78%    │ │
│  └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │
├─────────────────────────────────────────────────────────────┤
│  ┌──────────────────────────┐ ┌───────────────────────────┐ │
│  │ My Workload              │ │ Project Health            │ │
│  │ ┌────────────────────┐   │ │ ┌───────────────────────┐ │ │
│  │ │ 32h / 40h (80%)    │   │ │ │ 8 Healthy | 2 At Risk │ │ │
│  │ │ ████████░░         │   │ │ │ Avg Score: 76%        │ │ │
│  │ └────────────────────┘   │ │ └───────────────────────┘ │ │
│  └──────────────────────────┘ └───────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│  Quick Actions: [Spaces] [Workload] [Health] [Audit*]       │
└─────────────────────────────────────────────────────────────┘

API Design

GET /api/dashboard

Single endpoint aggregates all dashboard data to minimize frontend requests.

interface DashboardResponse {
  task_stats: {
    assigned_count: number      // Total tasks assigned to user
    due_this_week: number       // Tasks with due_date in current week
    overdue_count: number       // Tasks past due_date, not completed
    completion_rate: number     // Percentage (0-100)
  }
  workload: {
    allocated_hours: number
    capacity_hours: number
    load_percentage: number
    load_level: 'normal' | 'warning' | 'overloaded'
  }
  health_summary: {
    total_projects: number
    healthy_count: number
    at_risk_count: number
    critical_count: number
    average_health_score: number
  }
}

Data Sources

Widget Source Notes
Task Statistics pjctrl_tasks table Filter by assignee_id = current user
Workload Existing WorkloadService Reuse get_user_workload_detail()
Health Summary Existing HealthService Reuse get_dashboard() summary

Performance Considerations

  1. Single API Call: Frontend makes one request instead of three
  2. Query Optimization: Task stats use COUNT queries, not full rows
  3. Caching: Health summary already cached in Redis (5 min TTL)
  4. No N+1: Avoid loading related entities for counts

Component Structure

frontend/src/
├── pages/
│   └── Dashboard.tsx          # Main page (modified)
├── components/
│   ├── dashboard/
│   │   ├── StatisticsCard.tsx # Single stat card
│   │   ├── WorkloadWidget.tsx # Workload progress bar
│   │   ├── HealthWidget.tsx   # Health summary
│   │   └── QuickActions.tsx   # Navigation links
└── services/
    └── dashboard.ts           # API service (new)

Trade-offs

Decision: Single vs Multiple API Endpoints

Chosen: Single /api/dashboard endpoint

Rationale:

  • Reduces network round-trips (1 vs 3)
  • Simpler frontend loading state management
  • Data is always consistent (same timestamp)

Rejected Alternative: Use existing endpoints directly

  • Would require 3 parallel requests
  • More complex error handling
  • Harder to ensure data consistency