"""Pydantic response schemas for the leave-health insights surface.""" from __future__ import annotations from pydantic import BaseModel class CompanyBaseline(BaseModel): fiscal_year: int elapsed_fraction: float as_of: str active_population: int covered_population: int coverage_pct: float | None annual_entitled_total: float annual_used_total: float utilisation: float | None pace_index: float | None forfeit_at_risk_total: float comp_banked_total: float # Distribution of groups by health band across all three dimensions' # default (BU) view — drives the overview donut. health_distribution: dict[str, int] class GroupInsightRow(BaseModel): dimension: str key: str label: str member_count: int covered_count: int # Metric fields are null when the group is below the small-group privacy # guard (health == insufficient_data) — they are redacted server-side so a # 1-2 person "team" can never have its leave numbers reconstructed. annual_entitled_total: float | None annual_used_total: float | None annual_balance_total: float | None utilisation: float | None median_utilisation: float | None low_utiliser_count: int | None low_utiliser_pct: float | None forfeit_at_risk_total: float | None comp_banked_total: float | None pace_index: float | None vs_company: float | None health: str lead_person_id: str | None = None class OverviewResponse(BaseModel): baseline: CompanyBaseline thresholds: dict # Top "needs attention" groups (lowest utilisation, eligible groups only). attention_groups: list[GroupInsightRow] class MemberRow(BaseModel): person_id: str display_name: str employee_no: str | None department: str | None bu: str | None annual_entitled: float annual_used: float annual_balance: float forfeit_at_risk: float comp_balance: float utilisation: float | None has_quota: bool class GroupMembersResponse(BaseModel): dimension: str key: str label: str company_utilisation: float | None members: list[MemberRow] class TrendPoint(BaseModel): snapshot_date: str utilisation: float | None pace_index: float | None vs_company: float | None covered_count: int health: str | None class TrendResponse(BaseModel): dimension: str key: str points: list[TrendPoint]