class InstitutionRanking(BaseModel):
"""Ranking entry for a single institution aggregating artifact and AE service metrics."""
affiliation: str = Field(description="Normalized institution name.")
combined_score: int = Field(
ge=3,
description="Total score combining artifact_score, citation_score, and ae_score.",
)
artifact_score: int = Field(ge=0, description="Points from artifact contributions.")
artifact_citations: int | None = Field(
default=None,
ge=0,
description="Total citation count for artifacts. Present when citation tracking is enabled.",
)
citation_score: int | None = Field(
default=None,
ge=0,
description="Points from citations. Present when citation tracking is enabled.",
)
ae_score: int = Field(
ge=0,
description="Points from AE committee memberships (3 pts each) and chair roles (+2 pts each).",
)
ae_ratio: float | None = Field(
default=None,
description="Artifact-to-evaluation ratio. Null when ae_score is 0.",
)
role: Literal["Producer", "Consumer", "Balanced"] = Field(
description="Classification based on A:E ratio.",
)
artifacts: int = Field(ge=0, description="Total number of artifacts produced by this institution.")
badges_functional: int = Field(ge=0, description="Count of functional badges.")
badges_reproducible: int = Field(ge=0, description="Count of reproduced/replicated badges.")
ae_memberships: int = Field(ge=0, description="Number of AE committee memberships.")
chair_count: int = Field(ge=0, description="Number of AE chair roles.")
total_papers: int = Field(ge=0, description="Total DBLP paper count at tracked conferences.")
artifact_rate: float = Field(ge=0, le=100, description="Percentage of papers with artifacts.")
num_authors: int = Field(ge=1, description="Count of unique authors.")
conferences: list[str] = Field(description="List of conferences where the institution contributes.")
years: dict[str, int] = Field(description="Mapping of year (as string) to activity count.")
top_authors: list[TopAuthor] = Field(
max_length=20,
description="Top 20 authors from this institution, sorted by combined_score.",
)
model_config = {"extra": "forbid"}