Coverage for src/kwai/api/v1/teams/schemas.py: 100%

48 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2024-01-01 00:00 +0000

1"""Module that defines the schemas for the teams API.""" 

2 

3from typing import Annotated, Self 

4 

5from pydantic import BaseModel, Field 

6 

7from kwai.api.schemas.resources import TeamResourceIdentifier 

8from kwai.api.v1.resources import CountryResourceIdentifier 

9from kwai.api.v1.schemas import CountryDocument, CountryResource 

10from kwai.api.v1.teams.resources import TeamMemberResourceIdentifier 

11from kwai.core.json_api import Document, Relationship, ResourceData, ResourceMeta 

12from kwai.modules.teams.domain.team import TeamEntity 

13from kwai.modules.teams.domain.team_member import TeamMember 

14 

15 

16class TeamMemberAttributes(BaseModel): 

17 """Attributes for a team member.""" 

18 

19 active: bool 

20 first_name: str 

21 last_name: str 

22 license_number: str 

23 license_end_date: str 

24 gender: int 

25 birthdate: str 

26 active_in_club: bool 

27 

28 

29class TeamMemberRelationships(BaseModel): 

30 """Relationships for a team member JSON:API resource.""" 

31 

32 nationality: Relationship[CountryResourceIdentifier] 

33 team: Relationship[TeamResourceIdentifier] | None = None 

34 

35 

36class TeamMemberResource( 

37 TeamMemberResourceIdentifier, 

38 ResourceData[TeamMemberAttributes, TeamMemberRelationships], 

39): 

40 """A JSON:API resource for a team member.""" 

41 

42 

43TeamMemberInclude = Annotated[CountryResource, Field(discriminator="type")] 

44 

45 

46class TeamMemberDocument(Document[TeamMemberResource, TeamMemberInclude]): 

47 """A JSON:API document for one or more team members.""" 

48 

49 @classmethod 

50 def create(cls, team_member: TeamMember, team: TeamEntity | None = None) -> Self: 

51 """Create a team member document.""" 

52 nationality_document = CountryDocument.create(team_member.member.nationality) 

53 

54 team_member_resource = TeamMemberResource( 

55 id=str(team_member.member.uuid), 

56 attributes=TeamMemberAttributes( 

57 active=team_member.active, 

58 first_name=team_member.member.name.first_name, 

59 last_name=team_member.member.name.last_name, 

60 license_number=team_member.member.license.number, 

61 license_end_date=str(team_member.member.license.end_date), 

62 gender=team_member.member.gender, 

63 birthdate=str(team_member.member.birthdate), 

64 active_in_club=team_member.member.is_active_in_club, 

65 ), 

66 meta=ResourceMeta( 

67 created_at=str(team_member.traceable_time.created_at), 

68 updated_at=str(team_member.traceable_time.updated_at), 

69 ), 

70 ) 

71 team_member_resource.relationships = TeamMemberRelationships( 

72 nationality=Relationship[CountryResourceIdentifier]( 

73 data=CountryResourceIdentifier(id=nationality_document.resource.id), 

74 ), 

75 team=( 

76 None 

77 if team is None 

78 else Relationship[TeamResourceIdentifier]( 

79 data=TeamResourceIdentifier(id=str(team.id)) 

80 ) 

81 ), 

82 ) 

83 

84 return cls(data=team_member_resource, included={nationality_document.resource}) 

85 

86 

87class TeamAttributes(BaseModel): 

88 """Attributes for the team JSON:API resource.""" 

89 

90 name: str 

91 active: bool 

92 remark: str 

93 

94 

95class TeamRelationships(BaseModel): 

96 """Relationships for a team JSON:API resource.""" 

97 

98 team_members: Relationship[TeamMemberResourceIdentifier] 

99 

100 

101class TeamResource( 

102 TeamResourceIdentifier, ResourceData[TeamAttributes, TeamRelationships] 

103): 

104 """A JSON:API resource for a team.""" 

105 

106 

107TeamInclude = Annotated[ 

108 TeamMemberResource | CountryResource, Field(discriminator="type") 

109] 

110 

111 

112class TeamDocument(Document[TeamResource, TeamInclude]): 

113 """A JSON:API document for one or more teams.""" 

114 

115 @classmethod 

116 def create(cls, team: TeamEntity) -> Self: 

117 """Create a team document from a team entity.""" 

118 team_member_document = TeamMemberDocument(data=[], included=set()) 

119 for team_member in team.members.values(): 

120 team_member_document.merge(TeamMemberDocument.create(team_member)) 

121 

122 team_resource = TeamResource( 

123 id=str(team.id), 

124 attributes=TeamAttributes( 

125 name=team.name, active=team.is_active, remark=team.remark 

126 ), 

127 relationships=TeamRelationships( 

128 team_members=Relationship[TeamMemberResourceIdentifier]( 

129 data=team_member_document.resources 

130 ) 

131 ), 

132 ) 

133 

134 included: set[TeamInclude] = set(team_member_document.resources) 

135 included = included.union(team_member_document.included) 

136 

137 return TeamDocument(data=team_resource, included=included)