- Backend (FastAPI):
- Workload heatmap API with load level calculation
- User workload detail endpoint with task breakdown
- Redis caching for workload calculations (1hr TTL)
- Department isolation and access control
- WorkloadSnapshot model for historical data
- Alembic migration for workload_snapshots table
- API Endpoints:
- GET /api/workload/heatmap - Team workload overview
- GET /api/workload/user/{id} - User workload detail
- GET /api/workload/me - Current user workload
- Load Levels:
- normal: <80%, warning: 80-99%, overloaded: >=100%
- Tests:
- 26 unit/API tests
- 15 E2E automated tests
- 77 total tests passing
- OpenSpec:
- add-resource-workload change archived
- resource-management spec updated
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
79 lines
1.9 KiB
Python
79 lines
1.9 KiB
Python
from pydantic import BaseModel
|
|
from typing import Optional, List
|
|
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
from enum import Enum
|
|
|
|
|
|
class LoadLevel(str, Enum):
|
|
"""Workload level classification."""
|
|
NORMAL = "normal"
|
|
WARNING = "warning"
|
|
OVERLOADED = "overloaded"
|
|
UNAVAILABLE = "unavailable"
|
|
|
|
|
|
class TaskWorkloadInfo(BaseModel):
|
|
"""Task information for workload detail view."""
|
|
task_id: str
|
|
title: str
|
|
project_id: str
|
|
project_name: str
|
|
due_date: Optional[datetime] = None
|
|
original_estimate: Optional[Decimal] = None
|
|
status: Optional[str] = None
|
|
|
|
|
|
class UserWorkloadSummary(BaseModel):
|
|
"""Summary of a user's workload for heatmap display."""
|
|
user_id: str
|
|
user_name: str
|
|
department_id: Optional[str] = None
|
|
department_name: Optional[str] = None
|
|
capacity_hours: Decimal
|
|
allocated_hours: Decimal
|
|
load_percentage: Optional[Decimal] = None
|
|
load_level: LoadLevel
|
|
task_count: int
|
|
|
|
|
|
class WorkloadHeatmapResponse(BaseModel):
|
|
"""Response for workload heatmap API."""
|
|
week_start: date
|
|
week_end: date
|
|
users: List[UserWorkloadSummary]
|
|
|
|
|
|
class UserWorkloadDetail(BaseModel):
|
|
"""Detailed workload for a specific user."""
|
|
user_id: str
|
|
user_name: str
|
|
week_start: date
|
|
week_end: date
|
|
capacity_hours: Decimal
|
|
allocated_hours: Decimal
|
|
load_percentage: Optional[Decimal] = None
|
|
load_level: LoadLevel
|
|
tasks: List[TaskWorkloadInfo]
|
|
|
|
|
|
class WorkloadSnapshotResponse(BaseModel):
|
|
"""Response for workload snapshot."""
|
|
id: str
|
|
user_id: str
|
|
week_start: date
|
|
allocated_hours: Decimal
|
|
capacity_hours: Decimal
|
|
load_percentage: Decimal
|
|
task_count: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class CapacityUpdate(BaseModel):
|
|
"""Request to update user capacity."""
|
|
capacity: Decimal
|