Coverage for api_client/models.py: 100.00%

112 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2026-04-13 11:37 +0000

1""" 

2Auto-generated Pydantic models from OpenAPI schema. 

3 

4MANUAL OVERRIDE (2025-10-29): DivisionCreate and DivisionUpdate models 

5have been manually updated to support league_id. These will be regenerated 

6from OpenAPI schema after Phase 2 backend API updates. 

7 

8DO NOT EDIT THIS FILE MANUALLY (except for temporary overrides). 

9Regenerate with: uv run python scripts/generate_api_models.py 

10""" 

11 

12# generated by datamodel-codegen: 

13# filename: openapi.json 

14# timestamp: 2025-10-06T14:50:01+00:00 

15 

16from __future__ import annotations 

17 

18from pydantic import BaseModel, Field 

19 

20 

21class AgeGroupCreate(BaseModel): 

22 name: str = Field(..., title="Name") 

23 

24 

25class AgeGroupUpdate(BaseModel): 

26 name: str = Field(..., title="Name") 

27 

28 

29class DivisionCreate(BaseModel): 

30 name: str = Field(..., title="Name") 

31 description: str | None = Field(None, title="Description") 

32 league_id: int = Field(..., title="League Id") # MANUAL: Added for league layer support 

33 

34 

35class DivisionUpdate(BaseModel): 

36 name: str | None = Field(None, title="Name") 

37 description: str | None = Field(None, title="Description") 

38 league_id: int | None = Field(None, title="League Id") # MANUAL: Added for league layer support 

39 

40 

41class EnhancedGame(BaseModel): 

42 match_date: str = Field(..., title="Match Date") # MANUAL: Fixed - backend expects match_date not game_date 

43 home_team_id: int = Field(..., title="Home Team Id") 

44 away_team_id: int = Field(..., title="Away Team Id") 

45 home_score: int = Field(..., title="Home Score") 

46 away_score: int = Field(..., title="Away Score") 

47 season_id: int = Field(..., title="Season Id") 

48 age_group_id: int = Field(..., title="Age Group Id") 

49 match_type_id: int = Field( 

50 ..., title="Match Type Id" 

51 ) # MANUAL: Fixed - backend expects match_type_id not game_type_id 

52 division_id: int | None = Field(None, title="Division Id") 

53 status: str | None = Field("scheduled", title="Status") 

54 created_by: str | None = Field(None, title="Created By") 

55 updated_by: str | None = Field(None, title="Updated By") 

56 source: str = Field("manual", title="Source") 

57 

58 

59class GamePatch(BaseModel): 

60 """ 

61 Model for partial game updates. 

62 """ 

63 

64 home_score: int | None = Field(None, title="Home Score") 

65 away_score: int | None = Field(None, title="Away Score") 

66 match_status: str | None = Field(None, title="Match Status") 

67 game_date: str | None = Field(None, title="Game Date") 

68 home_team_id: int | None = Field(None, title="Home Team Id") 

69 away_team_id: int | None = Field(None, title="Away Team Id") 

70 season_id: int | None = Field(None, title="Season Id") 

71 age_group_id: int | None = Field(None, title="Age Group Id") 

72 game_type_id: int | None = Field(None, title="Game Type Id") 

73 division_id: int | None = Field(None, title="Division Id") 

74 status: str | None = Field(None, title="Status") 

75 

76 

77class RefreshTokenRequest(BaseModel): 

78 refresh_token: str = Field(..., title="Refresh Token") 

79 

80 

81class RoleUpdate(BaseModel): 

82 user_id: str = Field(..., title="User Id") 

83 role: str = Field(..., title="Role") 

84 team_id: int | None = Field(None, title="Team Id") 

85 

86 

87class SeasonCreate(BaseModel): 

88 name: str = Field(..., title="Name") 

89 start_date: str = Field(..., title="Start Date") 

90 end_date: str = Field(..., title="End Date") 

91 

92 

93class SeasonUpdate(BaseModel): 

94 name: str = Field(..., title="Name") 

95 start_date: str = Field(..., title="Start Date") 

96 end_date: str = Field(..., title="End Date") 

97 

98 

99class Team(BaseModel): 

100 name: str = Field(..., title="Name") 

101 city: str = Field(..., title="City") 

102 age_group_ids: list[int] = Field(..., title="Age Group Ids") 

103 division_id: int = Field(..., title="Division Id") # MANUAL: Fixed - backend expects singular division_id 

104 club_id: int | None = Field(None, title="Club Id") 

105 academy_team: bool | None = Field(False, title="Academy Team") 

106 

107 

108class TeamGameTypeMapping(BaseModel): 

109 game_type_id: int = Field(..., title="Game Type Id") 

110 age_group_id: int = Field(..., title="Age Group Id") 

111 

112 

113class TeamMappingCreate(BaseModel): 

114 team_id: int = Field(..., title="Team Id") 

115 age_group_id: int = Field(..., title="Age Group Id") 

116 division_id: int = Field(..., title="Division Id") 

117 

118 

119class TeamUpdate(BaseModel): 

120 name: str = Field(..., title="Name") 

121 city: str = Field(..., title="City") 

122 academy_team: bool | None = Field(False, title="Academy Team") 

123 

124 

125class UserLogin(BaseModel): 

126 email: str = Field(..., title="Email") 

127 password: str = Field(..., title="Password") 

128 

129 

130class UserProfile(BaseModel): 

131 display_name: str | None = Field(None, title="Display Name") 

132 role: str | None = Field(None, title="Role") 

133 team_id: int | None = Field(None, title="Team Id") 

134 player_number: int | None = Field(None, title="Player Number") 

135 positions: list[str] | None = Field(None, title="Positions") 

136 

137 

138class UserSignup(BaseModel): 

139 email: str = Field(..., title="Email") 

140 password: str = Field(..., title="Password") 

141 display_name: str | None = Field(None, title="Display Name") 

142 

143 

144class ValidationError(BaseModel): 

145 loc: list[str | int] = Field(..., title="Location") 

146 msg: str = Field(..., title="Message") 

147 type: str = Field(..., title="Error Type") 

148 

149 

150class HTTPValidationError(BaseModel): 

151 detail: list[ValidationError] | None = Field(None, title="Detail") 

152 

153 

154# Re-exports from backend/models/ (single source of truth) 

155# These allow api_client consumers to import models without knowing the internal layout. 

156 

157from models.auth import ( # noqa: F401 

158 AdminPlayerTeamAssignment, 

159 AdminPlayerUpdate, 

160 PlayerCustomization, 

161 PlayerHistoryCreate, 

162 PlayerHistoryUpdate, 

163 ProfilePhotoSlot, 

164 UserProfileUpdate, 

165) 

166from models.lineup import LineupSave # noqa: F401 

167from models.live_match import GoalEvent, LiveMatchClock, MessageEvent # noqa: F401 

168from models.matches import MatchSubmissionData # noqa: F401 

169from models.playoffs import AdvanceWinnerRequest, GenerateBracketRequest # noqa: F401 

170from models.roster import ( # noqa: F401 

171 BulkRenumberRequest, 

172 BulkRosterCreate, 

173 BulkRosterPlayer, 

174 JerseyNumberUpdate, 

175 RenumberEntry, 

176 RosterPlayerCreate, 

177 RosterPlayerUpdate, 

178) 

179 

180 

181# Invite request models — plain duplicates to avoid EmailStr dependency in client context 

182class InviteRequestCreate(BaseModel): 

183 """Create an invite request (public endpoint).""" 

184 

185 email: str = Field(..., description="Email address of the requester") 

186 name: str = Field(..., min_length=1, max_length=255, description="Name of the requester") 

187 team: str | None = Field(None, max_length=255, description="Team or club affiliation") 

188 reason: str | None = Field(None, description="Reason for wanting to join") 

189 

190 

191class InviteRequestStatusUpdate(BaseModel): 

192 """Update invite request status (admin only).""" 

193 

194 status: str = Field(..., pattern="^(pending|approved|rejected)$") 

195 admin_notes: str | None = Field(None, description="Admin notes about the decision") 

196 

197 

198# Channel access request models 

199class ChannelAccessRequestCreate(BaseModel): 

200 """Create or update a channel access request (logged-in users).""" 

201 

202 telegram: bool = False 

203 discord: bool = False 

204 telegram_handle: str | None = None 

205 discord_handle: str | None = None 

206 

207 

208class ChannelAccessStatusUpdate(BaseModel): 

209 """Update per-platform status on a channel access request (admin only).""" 

210 

211 platform: str = Field(..., pattern="^(telegram|discord)$") 

212 status: str = Field(..., pattern="^(approved|denied)$") 

213 admin_notes: str | None = None