from pydantic import BaseModel, Field from typing import List, Optional, Dict from datetime import datetime, date class DeliveryHealthMetrics(BaseModel): """Metrics for delivery health analysis""" sprint_id: Optional[str] = None sprint_name: Optional[str] = None period_start: date period_end: date # Velocity Metrics planned_story_points: float = 0 completed_story_points: float = 0 velocity: float = 0 velocity_trend: float = 0 # percentage change from previous period # Completion Metrics total_issues: int = 0 completed_issues: int = 0 completion_rate: float = 0 # Time Metrics avg_cycle_time_hours: float = 0 avg_lead_time_hours: float = 0 # Quality Indicators blocked_issues_count: int = 0 overdue_issues_count: int = 0 reopened_issues_count: int = 0 # Risk Indicators at_risk_issues: int = 0 health_score: float = 0 # 0-100 class ProductivityMetrics(BaseModel): """Workforce productivity metrics""" team_member_id: str team_member_name: str period_start: date period_end: date # Activity Metrics issues_completed: int = 0 story_points_completed: float = 0 code_commits: int = 0 # from GitHub pull_requests: int = 0 # from GitHub # Time Metrics total_hours_logged: float = 0 avg_hours_per_day: float = 0 # Efficiency Metrics avg_issue_completion_time_hours: float = 0 productivity_score: float = 0 # 0-100 # Workload Metrics current_assigned_issues: int = 0 current_story_points: float = 0 utilization_rate: float = 0 # percentage class CostEfficiencyMetrics(BaseModel): """Cost and efficiency analysis""" period_start: date period_end: date project_key: Optional[str] = None # Resource Metrics total_team_members: int = 0 total_hours_logged: float = 0 estimated_cost: float = 0 # based on hours # Output Metrics features_delivered: int = 0 story_points_delivered: float = 0 # Efficiency Ratios cost_per_feature: float = 0 cost_per_story_point: float = 0 hours_per_story_point: float = 0 # Waste Indicators blocked_time_hours: float = 0 rework_hours: float = 0 waste_percentage: float = 0 class TeamCapacityMetrics(BaseModel): """Team capacity and utilization""" team_id: Optional[str] = None team_name: str period_start: date period_end: date # Capacity Metrics total_capacity_hours: float = 0 allocated_hours: float = 0 available_hours: float = 0 utilization_rate: float = 0 # Workload Distribution team_members: List[Dict] = Field(default_factory=list) overloaded_members: int = 0 underutilized_members: int = 0 # Sprint Metrics current_sprint_load: float = 0 forecasted_capacity: float = 0 class RiskAlert(BaseModel): """Risk and alert model""" alert_id: str alert_type: str # delivery_delay, cost_overrun, resource_shortage, quality_issue severity: str # critical, high, medium, low title: str description: str affected_entity: str # sprint, project, team_member entity_id: str detected_at: datetime suggested_action: Optional[str] = None metrics: Dict = Field(default_factory=dict) class InsightRecommendation(BaseModel): """AI-generated insights and recommendations""" insight_id: str category: str # delivery, productivity, cost, resource title: str description: str confidence_score: float = 0 # 0-1 impact_level: str # high, medium, low recommendations: List[str] = Field(default_factory=list) supporting_data: Dict = Field(default_factory=dict) generated_at: datetime class KanbanFlowMetrics(BaseModel): """Kanban flow efficiency metrics""" board_id: int board_name: str period_start: date period_end: date # Flow Metrics throughput: int = 0 # Issues completed in period avg_cycle_time_days: float = 0 avg_lead_time_days: float = 0 flow_efficiency: float = 0 # 0-100 # WIP Metrics current_wip: int = 0 avg_wip: float = 0 wip_violations: int = 0 # Number of times WIP limits were exceeded # Column Metrics bottleneck_column: Optional[str] = None bottleneck_score: float = 0 # Predictability throughput_variance: float = 0 cycle_time_variance: float = 0 # Health Score flow_health_score: float = 0 # 0-100 class KanbanColumnAnalysis(BaseModel): """Analysis for a specific Kanban column""" column_name: str statuses: List[str] # Current State current_issue_count: int = 0 wip_limit_min: Optional[int] = None wip_limit_max: Optional[int] = None is_over_wip_limit: bool = False # Flow Metrics avg_time_in_column_days: float = 0 throughput: int = 0 # Issues exited this column # Efficiency utilization_rate: float = 0 # current / max limit is_bottleneck: bool = False bottleneck_score: float = 0 # Higher = more of a bottleneck class KanbanCumulativeFlow(BaseModel): """Cumulative flow diagram data""" board_id: int period_start: date period_end: date # Daily snapshots data_points: List[Dict] = Field(default_factory=list) # Each data point: {date, column_name, issue_count} class WIPLimitRecommendation(BaseModel): """WIP limit optimization recommendations""" column_name: str current_limit: Optional[int] recommended_min: int recommended_max: int reasoning: str confidence_score: float = 0 # 0-1