Coverage for postrfp/shared/serial/scoremodels.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-22 21:34 +0000

1from typing import Optional, Dict, Annotated 

2from pydantic import BaseModel, ConfigDict, Field 

3 

4from postrfp.shared.serial.common import ScoringModel 

5 

6 

7# Type aliases for better TypeScript generation 

8SectionScores = Annotated[ 

9 Dict[int, float], 

10 Field( 

11 description="Dictionary mapping section IDs to their calculated scores", 

12 json_schema_extra={ 

13 "example": {"1": 85.5, "2": 92.0, "3": 78.3}, 

14 "additionalProperties": {"type": "number"}, 

15 }, 

16 ), 

17] 

18 

19QuestionScores = Annotated[ 

20 Dict[int, float], 

21 Field( 

22 description="Dictionary mapping question IDs to their calculated scores", 

23 json_schema_extra={ 

24 "example": {"1": 90.0, "2": 85.0, "3": 88.5, "4": 76.0}, 

25 "additionalProperties": {"type": "number"}, 

26 }, 

27 ), 

28] 

29 

30 

31class AttrModel(BaseModel): 

32 model_config = ConfigDict(from_attributes=True) 

33 

34 

35class QuestionScore(AttrModel): 

36 question_id: int 

37 issue_id: int 

38 scoreset_id: Optional[str] = None 

39 score: Optional[float] = None 

40 

41 

42class SectionScore(AttrModel): 

43 section_id: int 

44 issue_id: int 

45 question_count: int 

46 questions_scored: int 

47 score: Optional[float] = None 

48 

49 

50class ScoreSummary(AttrModel): 

51 subsections: list[SectionScore] 

52 questions: list[QuestionScore] 

53 

54 

55class NodeScores(BaseModel): 

56 pass 

57 

58 

59class IssueScores(AttrModel): 

60 total_score: float = Field(description="Total calculated score for the issue") 

61 section_scores: SectionScores 

62 question_scores: QuestionScores 

63 

64 

65class CalculatedScores(AttrModel): 

66 scoring_model: ScoringModel 

67 scores: dict[int, IssueScores]