@taimos/radball-digital-api 0.0.40 → 0.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/docs/assets/navigation.js +1 -1
  2. package/docs/assets/search.js +1 -1
  3. package/docs/enums/RegistrationPermission.html +4 -0
  4. package/docs/modules.html +1 -1
  5. package/docs/types/Association.html +3 -2
  6. package/docs/types/Competition.html +18 -0
  7. package/docs/types/CompetitionGroup.html +11 -0
  8. package/docs/types/CompetitionGroupStatistics.html +6 -0
  9. package/docs/types/CompetitionGroupView.html +7 -0
  10. package/docs/types/CompetitionRegistrationError.html +6 -0
  11. package/docs/types/CompetitionRegistrationResult.html +5 -0
  12. package/docs/types/CompetitionTeam.html +12 -0
  13. package/docs/types/ModifyCompetitionGroupInput.html +7 -0
  14. package/docs/types/ModifyCompetitionInput.html +15 -0
  15. package/docs/types/ModifyCompetitionTeamInput.html +9 -0
  16. package/docs/types/Mutation.html +13 -2
  17. package/docs/types/MutationAddCompetitionArgs.html +2 -0
  18. package/docs/types/MutationAddCompetitionGroupArgs.html +2 -0
  19. package/docs/types/MutationAddCompetitionTeamArgs.html +2 -0
  20. package/docs/types/MutationModifyCompetitionArgs.html +2 -0
  21. package/docs/types/MutationModifyCompetitionGroupArgs.html +2 -0
  22. package/docs/types/MutationModifyCompetitionTeamArgs.html +2 -0
  23. package/docs/types/MutationRegisterCompetitionTeamsArgs.html +2 -0
  24. package/docs/types/MutationRemoveCompetitionArgs.html +2 -0
  25. package/docs/types/MutationRemoveCompetitionGroupArgs.html +2 -0
  26. package/docs/types/MutationRemoveCompetitionTeamArgs.html +2 -0
  27. package/docs/types/MutationUpdateCompetitionTeamGroupArgs.html +3 -0
  28. package/docs/types/Query.html +11 -2
  29. package/docs/types/QueryCanClubRegisterForCompetitionArgs.html +3 -0
  30. package/docs/types/QueryGetCompetitionByIdArgs.html +2 -0
  31. package/docs/types/QueryGetCompetitionGroupByIdArgs.html +2 -0
  32. package/docs/types/QueryGetCompetitionGroupViewArgs.html +2 -0
  33. package/docs/types/QueryGetCompetitionTeamByIdArgs.html +2 -0
  34. package/docs/types/QueryGetListOfCompetitionsArgs.html +2 -0
  35. package/docs/types/QueryGetListOfGroupsInCompetitionArgs.html +2 -0
  36. package/docs/types/QueryGetListOfTeamsInCompetitionArgs.html +2 -0
  37. package/docs/types/QueryGetListOfTeamsInCompetitionGroupArgs.html +2 -0
  38. package/docs/types/RegisterCompetitionTeamInput.html +9 -0
  39. package/docs/types/RegisterCompetitionTeamsInput.html +5 -0
  40. package/docs/types/RegistrationEligibility.html +6 -0
  41. package/docs/types/SaveCompetitionGroupInput.html +7 -0
  42. package/docs/types/SaveCompetitionInput.html +15 -0
  43. package/docs/types/SaveCompetitionTeamInput.html +10 -0
  44. package/lib/generated/graphql.model.generated.d.ts +252 -0
  45. package/lib/generated/graphql.model.generated.js +8 -2
  46. package/llm.md +1055 -440
  47. package/package.json +1 -1
  48. package/schema.graphql +235 -0
package/llm.md CHANGED
@@ -13,23 +13,91 @@ npm install @taimos/radball-digital-api
13
13
  ```typescript
14
14
  // Import GraphQL types
15
15
  import {
16
+ // Core entities
16
17
  Association,
17
18
  Season,
18
19
  League,
19
20
  LeagueGroup,
20
21
  LeagueGroupView,
21
- TeamDetail,
22
22
  LeagueGroupStatistics,
23
- Club,
24
23
  Team,
24
+ TeamDetail,
25
+ Club,
25
26
  Person,
26
27
  Gym,
27
28
  Game,
28
29
  MatchDay,
30
+ MatchdayTeam,
31
+ RankingEntry,
29
32
  PreferredMatchdayDate,
33
+ Address,
34
+ RefereeInfo,
35
+
36
+ // Competition/Tournament entities (NEW)
37
+ Competition,
38
+ CompetitionGroup,
39
+ CompetitionTeam,
40
+ CompetitionGroupView,
41
+ CompetitionGroupStatistics,
42
+ CompetitionRegistrationResult,
43
+ CompetitionRegistrationError,
44
+ RegistrationEligibility,
45
+
46
+ // Enums
47
+ PreferenceStatus,
48
+ RegistrationPermission,
49
+
50
+ // Save inputs (create)
30
51
  SaveAssociationInput,
31
52
  SaveClubInput,
53
+ SavePersonInput,
54
+ SaveSeasonInput,
55
+ SaveLeagueInput,
56
+ SaveLeagueGroupInput,
32
57
  SaveTeamInput,
58
+ SaveGymInput,
59
+ SaveMatchDayInput,
60
+ SaveMatchDayTeamInput,
61
+ SavePreferredMatchdayDateInput,
62
+ SaveCompetitionInput,
63
+ SaveCompetitionGroupInput,
64
+ SaveCompetitionTeamInput,
65
+
66
+ // Modify inputs (update)
67
+ ModifyAssociationInput,
68
+ ModifyClubInput,
69
+ ModifyPersonInput,
70
+ ModifySeasonInput,
71
+ ModifyLeagueInput,
72
+ ModifyLeagueGroupInput,
73
+ ModifyTeamInput,
74
+ ModifyGymInput,
75
+ ModifyMatchDayInput,
76
+ ModifyMatchDayTeamInput,
77
+ ModifyGameInput,
78
+ ModifyPreferredMatchdayDateInput,
79
+ ModifyCompetitionInput,
80
+ ModifyCompetitionGroupInput,
81
+ ModifyCompetitionTeamInput,
82
+
83
+ // Registration inputs
84
+ RegisterTeamInput,
85
+ RegisterTeamsForSeasonInput,
86
+ RegisterCompetitionTeamInput,
87
+ RegisterCompetitionTeamsInput,
88
+
89
+ // Other inputs
90
+ AddGameInput,
91
+ AddressInput,
92
+ RefereeInfoInput,
93
+ UpdateTeamGroupInput,
94
+
95
+ // Connection types (pagination)
96
+ ClubConnection,
97
+ GymConnection,
98
+ PersonConnection,
99
+
100
+ // Query and Mutation types
33
101
  Query,
34
102
  Mutation,
35
103
  Scalars
@@ -37,13 +105,27 @@ import {
37
105
 
38
106
  // Import validation functions
39
107
  import {
108
+ validateAddress,
40
109
  validateAssociation,
41
110
  validateClub,
42
- validateTeam,
111
+ validateGym,
112
+ validateLeague,
113
+ validateLeagueGroup,
43
114
  validatePerson,
115
+ validateSeason,
116
+ validateTeam,
117
+ checkAddress,
44
118
  checkAssociation,
45
119
  checkClub,
46
- ValidationCheckResult
120
+ checkGym,
121
+ checkLeague,
122
+ checkLeagueGroup,
123
+ checkPerson,
124
+ checkSeason,
125
+ checkTeam,
126
+ isSeasonOpenForRegistration,
127
+ ValidationCheckResult,
128
+ REGEX_EMAIL_FORMAT
47
129
  } from '@taimos/radball-digital-api';
48
130
 
49
131
  // Import REST API types
@@ -58,27 +140,28 @@ The library uses AWS AppSync scalar types:
58
140
 
59
141
  ```typescript
60
142
  type Scalars = {
61
- ID: string;
62
- String: string;
63
- Boolean: boolean;
64
- Int: number;
65
- Float: number;
66
- AWSDate: string; // Format: YYYY-MM-DD
67
- AWSDateTime: string; // ISO 8601 format
68
- AWSEmail: string; // Email address
69
- AWSURL: string; // URL string
70
- AWSTimestamp: number; // Unix timestamp
143
+ ID: { input: string; output: string };
144
+ String: { input: string; output: string };
145
+ Boolean: { input: boolean; output: boolean };
146
+ Int: { input: number; output: number };
147
+ Float: { input: number; output: number };
148
+ AWSDate: { input: string; output: string }; // Format: YYYY-MM-DD
149
+ AWSDateTime: { input: string; output: string }; // ISO 8601 format
150
+ AWSEmail: { input: string; output: string }; // Email address
151
+ AWSURL: { input: string; output: string }; // URL string
152
+ AWSPhone: { input: string; output: string }; // Phone number
153
+ AWSTimestamp: { input: string; output: string }; // Unix timestamp
71
154
  };
72
155
  ```
73
156
 
74
157
  ### Nullable Types
75
158
 
76
159
  ```typescript
77
- // Maybe<T> - Can be T, null, or undefined
78
- type Maybe<T> = T | null | undefined;
160
+ // Maybe<T> - Can be T or undefined
161
+ type Maybe<T> = T | undefined;
79
162
 
80
163
  // InputMaybe<T> - For input types
81
- type InputMaybe<T> = T | null | undefined;
164
+ type InputMaybe<T> = T | undefined;
82
165
  ```
83
166
 
84
167
  ## Core Entity Types
@@ -89,27 +172,58 @@ type InputMaybe<T> = T | null | undefined;
89
172
  // Type definition
90
173
  interface Association {
91
174
  __typename?: 'Association';
92
- createdAt: Scalars['AWSDateTime'];
93
- id: Scalars['ID'];
94
- name: Scalars['String'];
95
- shortName?: Maybe<Scalars['String']>;
96
- type: Scalars['String'];
97
- updatedAt: Scalars['AWSDateTime'];
175
+ id: Scalars['ID']['output'];
176
+ name: Scalars['String']['output'];
177
+ shortName: Scalars['String']['output'];
178
+ address: Address;
179
+ contactName: Scalars['String']['output'];
180
+ contactEmail: Scalars['AWSEmail']['output'];
181
+ phone?: Maybe<Scalars['String']['output']>;
182
+ website?: Maybe<Scalars['AWSURL']['output']>;
183
+ seasons?: Maybe<Array<Maybe<Season>>>;
184
+ competitions?: Maybe<Array<Maybe<Competition>>>;
185
+ coordinators: Array<Maybe<Person>>;
186
+ groupLeaders: Array<Maybe<Person>>;
98
187
  }
99
188
 
100
- // Create/Update input
189
+ // Create input
101
190
  interface SaveAssociationInput {
102
- id?: InputMaybe<Scalars['ID']>;
103
- name: Scalars['String'];
104
- shortName?: InputMaybe<Scalars['String']>;
105
- type: Scalars['String'];
191
+ name: Scalars['String']['input'];
192
+ shortName: Scalars['String']['input'];
193
+ address: AddressInput;
194
+ contactName: Scalars['String']['input'];
195
+ contactEmail: Scalars['AWSEmail']['input'];
196
+ phone?: InputMaybe<Scalars['String']['input']>;
197
+ website?: InputMaybe<Scalars['AWSURL']['input']>;
198
+ coordinators: Array<InputMaybe<Scalars['ID']['input']>>;
199
+ }
200
+
201
+ // Update input
202
+ interface ModifyAssociationInput {
203
+ id: Scalars['ID']['input'];
204
+ name: Scalars['String']['input'];
205
+ shortName: Scalars['String']['input'];
206
+ address: AddressInput;
207
+ contactName: Scalars['String']['input'];
208
+ contactEmail: Scalars['AWSEmail']['input'];
209
+ phone?: InputMaybe<Scalars['String']['input']>;
210
+ website?: InputMaybe<Scalars['AWSURL']['input']>;
211
+ coordinators: Array<InputMaybe<Scalars['ID']['input']>>;
106
212
  }
107
213
 
108
214
  // Usage example
109
215
  const newAssociation: SaveAssociationInput = {
110
216
  name: 'Deutscher Radball Verband',
111
217
  shortName: 'DRV',
112
- type: 'NATIONAL'
218
+ contactName: 'Max Mustermann',
219
+ contactEmail: 'info@drv.de',
220
+ address: {
221
+ street: 'Hauptstraße 1',
222
+ zip: '12345',
223
+ city: 'Berlin',
224
+ country: 'DE'
225
+ },
226
+ coordinators: []
113
227
  };
114
228
 
115
229
  // Validation
@@ -127,24 +241,30 @@ try {
127
241
  // Type definition
128
242
  interface Club {
129
243
  __typename?: 'Club';
130
- associationId: Scalars['ID'];
131
- createdAt: Scalars['AWSDateTime'];
132
- externalId?: Maybe<Scalars['String']>;
133
- id: Scalars['ID'];
134
- legacyId?: Maybe<Scalars['String']>;
135
- name: Scalars['String'];
136
- shortName?: Maybe<Scalars['String']>;
137
- updatedAt: Scalars['AWSDateTime'];
244
+ id: Scalars['ID']['output'];
245
+ name: Scalars['String']['output'];
246
+ shortName?: Maybe<Scalars['String']['output']>;
247
+ address?: Maybe<Address>;
248
+ email?: Maybe<Scalars['AWSEmail']['output']>;
249
+ resultServiceEmail?: Maybe<Scalars['AWSEmail']['output']>;
250
+ website?: Maybe<Scalars['AWSURL']['output']>;
251
+ association: Association;
252
+ contact?: Maybe<Person>;
253
+ additionalContacts?: Maybe<Array<Maybe<Person>>>;
254
+ teams?: Maybe<Array<Maybe<Team>>>;
138
255
  }
139
256
 
140
- // Create/Update input
257
+ // Create input
141
258
  interface SaveClubInput {
142
- associationId: Scalars['ID'];
143
- externalId?: InputMaybe<Scalars['String']>;
144
- id?: InputMaybe<Scalars['ID']>;
145
- legacyId?: InputMaybe<Scalars['String']>;
146
- name: Scalars['String'];
147
- shortName?: InputMaybe<Scalars['String']>;
259
+ associationId: Scalars['ID']['input'];
260
+ name: Scalars['String']['input'];
261
+ shortName?: InputMaybe<Scalars['String']['input']>;
262
+ address: AddressInput;
263
+ email?: InputMaybe<Scalars['AWSEmail']['input']>;
264
+ resultServiceEmail?: InputMaybe<Scalars['AWSEmail']['input']>;
265
+ website?: InputMaybe<Scalars['AWSURL']['input']>;
266
+ contactId: Scalars['ID']['input'];
267
+ additionalContactIds?: InputMaybe<Array<InputMaybe<Scalars['ID']['input']>>>;
148
268
  }
149
269
 
150
270
  // Usage example
@@ -152,47 +272,13 @@ const newClub: SaveClubInput = {
152
272
  associationId: 'association-123',
153
273
  name: 'RV Musterhausen',
154
274
  shortName: 'RVM',
155
- externalId: 'ext-456'
156
- };
157
- ```
158
-
159
- ### Team
160
-
161
- ```typescript
162
- // Type definition
163
- interface Team {
164
- __typename?: 'Team';
165
- ageClass?: Maybe<Scalars['String']>;
166
- clubId: Scalars['ID'];
167
- createdAt: Scalars['AWSDateTime'];
168
- discipline: Scalars['String'];
169
- id: Scalars['ID'];
170
- legacyNumber?: Maybe<Scalars['Int']>;
171
- name: Scalars['String'];
172
- secondaryClubId?: Maybe<Scalars['ID']>;
173
- status?: Maybe<Scalars['String']>;
174
- updatedAt: Scalars['AWSDateTime'];
175
- }
176
-
177
- // Create/Update input
178
- interface SaveTeamInput {
179
- ageClass?: InputMaybe<Scalars['String']>;
180
- clubId: Scalars['ID'];
181
- discipline: Scalars['String'];
182
- id?: InputMaybe<Scalars['ID']>;
183
- legacyNumber?: InputMaybe<Scalars['Int']>;
184
- name: Scalars['String'];
185
- secondaryClubId?: InputMaybe<Scalars['ID']>;
186
- status?: InputMaybe<Scalars['String']>;
187
- }
188
-
189
- // Usage example
190
- const newTeam: SaveTeamInput = {
191
- clubId: 'club-123',
192
- name: 'RV Musterhausen I',
193
- discipline: 'RADBALL',
194
- ageClass: 'ELITE',
195
- status: 'ACTIVE'
275
+ contactId: 'person-456',
276
+ address: {
277
+ street: 'Sportplatz 5',
278
+ zip: '54321',
279
+ city: 'Musterhausen',
280
+ country: 'DE'
281
+ }
196
282
  };
197
283
  ```
198
284
 
@@ -202,57 +288,44 @@ const newTeam: SaveTeamInput = {
202
288
  // Type definition
203
289
  interface Person {
204
290
  __typename?: 'Person';
291
+ id: Scalars['ID']['output'];
292
+ firstName: Scalars['String']['output'];
293
+ lastName: Scalars['String']['output'];
294
+ email?: Maybe<Scalars['AWSEmail']['output']>;
295
+ phone?: Maybe<Scalars['String']['output']>;
296
+ dateOfBirth?: Maybe<Scalars['AWSDate']['output']>;
297
+ gender?: Maybe<Scalars['String']['output']>;
298
+ nationality?: Maybe<Scalars['String']['output']>;
299
+ uciCode?: Maybe<Scalars['String']['output']>;
205
300
  address?: Maybe<Address>;
206
- birthdate?: Maybe<Scalars['AWSDate']>;
207
- clubId?: Maybe<Scalars['ID']>;
208
- createdAt: Scalars['AWSDateTime'];
209
- email?: Maybe<Scalars['AWSEmail']>;
210
- firstname?: Maybe<Scalars['String']>;
211
- gender?: Maybe<Scalars['String']>;
212
- id: Scalars['ID'];
213
- lastname?: Maybe<Scalars['String']>;
214
- legacyId?: Maybe<Scalars['String']>;
215
- phone?: Maybe<Scalars['String']>;
216
- roles?: Maybe<Array<Scalars['String']>>;
217
- updatedAt: Scalars['AWSDateTime'];
218
- }
219
-
220
- // Address sub-type
221
- interface Address {
222
- __typename?: 'Address';
223
- city?: Maybe<Scalars['String']>;
224
- country?: Maybe<Scalars['String']>;
225
- number?: Maybe<Scalars['String']>;
226
- street?: Maybe<Scalars['String']>;
227
- zip?: Maybe<Scalars['String']>;
301
+ club?: Maybe<Club>;
302
+ subjectId?: Maybe<Scalars['ID']['output']>;
228
303
  }
229
304
 
230
- // Create/Update input
305
+ // Create input
231
306
  interface SavePersonInput {
307
+ clubId: Scalars['ID']['input'];
308
+ firstName: Scalars['String']['input'];
309
+ lastName: Scalars['String']['input'];
310
+ email?: InputMaybe<Scalars['AWSEmail']['input']>;
311
+ phone?: InputMaybe<Scalars['String']['input']>;
312
+ dateOfBirth?: InputMaybe<Scalars['AWSDate']['input']>;
313
+ gender?: InputMaybe<Scalars['String']['input']>;
314
+ nationality?: InputMaybe<Scalars['String']['input']>;
315
+ uciCode?: InputMaybe<Scalars['String']['input']>;
232
316
  address?: InputMaybe<AddressInput>;
233
- birthdate?: InputMaybe<Scalars['AWSDate']>;
234
- clubId?: InputMaybe<Scalars['ID']>;
235
- email?: InputMaybe<Scalars['AWSEmail']>;
236
- firstname?: InputMaybe<Scalars['String']>;
237
- gender?: InputMaybe<Scalars['String']>;
238
- id?: InputMaybe<Scalars['ID']>;
239
- lastname?: InputMaybe<Scalars['String']>;
240
- legacyId?: InputMaybe<Scalars['String']>;
241
- phone?: InputMaybe<Scalars['String']>;
242
- roles?: InputMaybe<Array<Scalars['String']>>;
243
317
  }
244
318
 
245
319
  // Usage example
246
320
  const newPerson: SavePersonInput = {
247
- firstname: 'Max',
248
- lastname: 'Mustermann',
321
+ clubId: 'club-123',
322
+ firstName: 'Max',
323
+ lastName: 'Mustermann',
249
324
  email: 'max@example.com',
250
- birthdate: '1990-01-15',
325
+ dateOfBirth: '1990-01-15',
251
326
  gender: 'MALE',
252
- roles: ['PLAYER'],
253
327
  address: {
254
- street: 'Hauptstraße',
255
- number: '123',
328
+ street: 'Hauptstraße 123',
256
329
  zip: '12345',
257
330
  city: 'Musterhausen',
258
331
  country: 'DE'
@@ -260,36 +333,68 @@ const newPerson: SavePersonInput = {
260
333
  };
261
334
  ```
262
335
 
336
+ ### Address
337
+
338
+ ```typescript
339
+ // Type definition
340
+ interface Address {
341
+ __typename?: 'Address';
342
+ street?: Maybe<Scalars['String']['output']>;
343
+ zip?: Maybe<Scalars['String']['output']>;
344
+ city?: Maybe<Scalars['String']['output']>;
345
+ country?: Maybe<Scalars['String']['output']>;
346
+ }
347
+
348
+ // Input type
349
+ interface AddressInput {
350
+ street?: InputMaybe<Scalars['String']['input']>;
351
+ zip?: InputMaybe<Scalars['String']['input']>;
352
+ city?: InputMaybe<Scalars['String']['input']>;
353
+ country?: InputMaybe<Scalars['String']['input']>;
354
+ }
355
+ ```
356
+
263
357
  ### Season
264
358
 
265
359
  ```typescript
266
360
  // Type definition
267
361
  interface Season {
268
362
  __typename?: 'Season';
269
- associationId: Scalars['ID'];
270
- createdAt: Scalars['AWSDateTime'];
271
- endDate: Scalars['AWSDate'];
272
- id: Scalars['ID'];
273
- minimumAgePlayerDate?: Maybe<Scalars['AWSDate']>;
274
- minimumAgeStaffDate?: Maybe<Scalars['AWSDate']>;
275
- name: Scalars['String'];
276
- registrationEndDate?: Maybe<Scalars['AWSDate']>;
277
- registrationStartDate?: Maybe<Scalars['AWSDate']>;
278
- startDate: Scalars['AWSDate'];
279
- updatedAt: Scalars['AWSDateTime'];
280
- }
281
-
282
- // Create/Update input
363
+ id: Scalars['ID']['output'];
364
+ name: Scalars['String']['output'];
365
+ startDate: Scalars['AWSDate']['output'];
366
+ endDate: Scalars['AWSDate']['output'];
367
+ registrationStart?: Maybe<Scalars['AWSDate']['output']>;
368
+ registrationEnd: Scalars['AWSDate']['output'];
369
+ leagueOrder?: Maybe<Array<Scalars['ID']['output']>>;
370
+ regulationFileUrl?: Maybe<Scalars['AWSURL']['output']>;
371
+ association: Association;
372
+ leagues?: Maybe<Array<Maybe<League>>>;
373
+ additionalEligibleAssociations?: Maybe<Array<Maybe<Association>>>;
374
+ }
375
+
376
+ // Create input
283
377
  interface SaveSeasonInput {
284
- associationId: Scalars['ID'];
285
- endDate: Scalars['AWSDate'];
286
- id?: InputMaybe<Scalars['ID']>;
287
- minimumAgePlayerDate?: InputMaybe<Scalars['AWSDate']>;
288
- minimumAgeStaffDate?: InputMaybe<Scalars['AWSDate']>;
289
- name: Scalars['String'];
290
- registrationEndDate?: InputMaybe<Scalars['AWSDate']>;
291
- registrationStartDate?: InputMaybe<Scalars['AWSDate']>;
292
- startDate: Scalars['AWSDate'];
378
+ associationId: Scalars['ID']['input'];
379
+ name: Scalars['String']['input'];
380
+ startDate: Scalars['AWSDate']['input'];
381
+ endDate: Scalars['AWSDate']['input'];
382
+ registrationStart?: InputMaybe<Scalars['AWSDate']['input']>;
383
+ registrationEnd: Scalars['AWSDate']['input'];
384
+ additionalEligibleAssociations: Array<InputMaybe<Scalars['ID']['input']>>;
385
+ }
386
+
387
+ // Update input (includes leagueOrder)
388
+ interface ModifySeasonInput {
389
+ id: Scalars['ID']['input'];
390
+ name: Scalars['String']['input'];
391
+ startDate: Scalars['AWSDate']['input'];
392
+ endDate: Scalars['AWSDate']['input'];
393
+ registrationStart?: InputMaybe<Scalars['AWSDate']['input']>;
394
+ registrationEnd: Scalars['AWSDate']['input'];
395
+ leagueOrder?: InputMaybe<Array<Scalars['ID']['input']>>;
396
+ regulationFileUrl?: InputMaybe<Scalars['AWSURL']['input']>;
397
+ additionalEligibleAssociations: Array<InputMaybe<Scalars['ID']['input']>>;
293
398
  }
294
399
 
295
400
  // Usage example
@@ -298,91 +403,538 @@ const newSeason: SaveSeasonInput = {
298
403
  name: 'Saison 2024/2025',
299
404
  startDate: '2024-09-01',
300
405
  endDate: '2025-06-30',
301
- registrationStartDate: '2024-07-01',
302
- registrationEndDate: '2024-08-15',
303
- minimumAgePlayerDate: '2009-01-01'
406
+ registrationStart: '2024-07-01',
407
+ registrationEnd: '2024-08-15',
408
+ additionalEligibleAssociations: []
304
409
  };
305
410
  ```
306
411
 
307
- ### League and LeagueGroup
412
+ ### League
308
413
 
309
414
  ```typescript
310
- // League type
415
+ // Type definition
311
416
  interface League {
312
417
  __typename?: 'League';
313
- associationId: Scalars['ID'];
314
- createdAt: Scalars['AWSDateTime'];
315
- discipline: Scalars['String'];
316
- id: Scalars['ID'];
317
- matchDayTemplate?: Maybe<Array<MatchDayTemplateEntry>>;
318
- matchdayBlockedDates?: Maybe<Array<Scalars['AWSDate']>>;
319
- matchdayReferenceDate?: Maybe<Scalars['AWSDate']>;
320
- minPlayerAge?: Maybe<Scalars['Int']>;
321
- name: Scalars['String'];
322
- order?: Maybe<Scalars['Int']>;
323
- seasonId: Scalars['ID'];
324
- updatedAt: Scalars['AWSDateTime'];
325
- }
326
-
327
- // LeagueGroup type
328
- interface LeagueGroup {
329
- __typename?: 'LeagueGroup';
330
- createdAt: Scalars['AWSDateTime'];
331
- id: Scalars['ID'];
332
- leader?: Maybe<Scalars['ID']>;
333
- leagueId: Scalars['ID'];
334
- name: Scalars['String'];
335
- teams?: Maybe<Array<Scalars['ID']>>;
336
- updatedAt: Scalars['AWSDateTime'];
418
+ id: Scalars['ID']['output'];
419
+ name: Scalars['String']['output'];
420
+ shortName?: Maybe<Scalars['String']['output']>;
421
+ description: Scalars['String']['output'];
422
+ minAge?: Maybe<Scalars['Int']['output']>;
423
+ maxAge?: Maybe<Scalars['Int']['output']>;
424
+ matchdayDates?: Maybe<Array<Scalars['AWSDate']['output']>>;
425
+ season: Season;
426
+ association: Association;
427
+ groups?: Maybe<Array<Maybe<LeagueGroup>>>;
337
428
  }
338
429
 
339
- // Create inputs
430
+ // Create input
340
431
  interface SaveLeagueInput {
341
- associationId: Scalars['ID'];
342
- discipline: Scalars['String'];
343
- id?: InputMaybe<Scalars['ID']>;
344
- matchDayTemplate?: InputMaybe<Array<MatchDayTemplateEntryInput>>;
345
- matchdayBlockedDates?: InputMaybe<Array<Scalars['AWSDate']>>;
346
- matchdayReferenceDate?: InputMaybe<Scalars['AWSDate']>;
347
- minPlayerAge?: InputMaybe<Scalars['Int']>;
348
- name: Scalars['String'];
349
- order?: InputMaybe<Scalars['Int']>;
350
- seasonId: Scalars['ID'];
432
+ seasonId: Scalars['ID']['input'];
433
+ name: Scalars['String']['input'];
434
+ shortName?: InputMaybe<Scalars['String']['input']>;
435
+ description: Scalars['String']['input'];
436
+ minAge?: InputMaybe<Scalars['Int']['input']>;
437
+ maxAge?: InputMaybe<Scalars['Int']['input']>;
438
+ matchdayDates?: InputMaybe<Array<Scalars['AWSDate']['input']>>;
351
439
  }
440
+ ```
441
+
442
+ ### LeagueGroup
352
443
 
444
+ ```typescript
445
+ // Type definition
446
+ interface LeagueGroup {
447
+ __typename?: 'LeagueGroup';
448
+ id: Scalars['ID']['output'];
449
+ name: Scalars['String']['output'];
450
+ shortName: Scalars['String']['output'];
451
+ number: Scalars['Int']['output'];
452
+ regulation: Scalars['String']['output'];
453
+ league: League;
454
+ season: Season;
455
+ association: Association;
456
+ leader?: Maybe<Person>;
457
+ }
458
+
459
+ // Create input
353
460
  interface SaveLeagueGroupInput {
354
- id?: InputMaybe<Scalars['ID']>;
355
- leader?: InputMaybe<Scalars['ID']>;
356
- leagueId: Scalars['ID'];
357
- name: Scalars['String'];
358
- teams?: InputMaybe<Array<Scalars['ID']>>;
461
+ leagueId: Scalars['ID']['input'];
462
+ name: Scalars['String']['input'];
463
+ shortName: Scalars['String']['input'];
464
+ number: Scalars['Int']['input'];
465
+ regulation: Scalars['String']['input'];
466
+ groupLeaderId?: InputMaybe<Scalars['ID']['input']>;
359
467
  }
360
468
  ```
361
469
 
362
- ### Game
470
+ ### Team
471
+
472
+ ```typescript
473
+ // Type definition
474
+ interface Team {
475
+ __typename?: 'Team';
476
+ id: Scalars['ID']['output'];
477
+ name: Scalars['String']['output'];
478
+ club: Club;
479
+ league: League;
480
+ leagueGroup?: Maybe<LeagueGroup>;
481
+ players: Array<Maybe<Person>>;
482
+ exemptionRequest?: Maybe<Scalars['String']['output']>;
483
+ secondRightToPlay?: Maybe<Scalars['Boolean']['output']>;
484
+ withoutCompetition?: Maybe<Scalars['Boolean']['output']>;
485
+ sgClub?: Maybe<Club>;
486
+ }
487
+
488
+ // Create input
489
+ interface SaveTeamInput {
490
+ clubId: Scalars['ID']['input'];
491
+ leagueId: Scalars['ID']['input'];
492
+ leagueGroupId?: InputMaybe<Scalars['ID']['input']>;
493
+ name: Scalars['String']['input'];
494
+ playerIds: Array<InputMaybe<Scalars['ID']['input']>>;
495
+ exemptionRequest?: InputMaybe<Scalars['String']['input']>;
496
+ secondRightToPlay?: InputMaybe<Scalars['Boolean']['input']>;
497
+ withoutCompetition?: InputMaybe<Scalars['Boolean']['input']>;
498
+ sgClubId?: InputMaybe<Scalars['ID']['input']>;
499
+ }
500
+
501
+ // Register team input (for season registration)
502
+ interface RegisterTeamInput {
503
+ leagueId: Scalars['ID']['input'];
504
+ name: Scalars['String']['input'];
505
+ playerIds: Array<Scalars['ID']['input']>;
506
+ exemptionRequest?: InputMaybe<Scalars['String']['input']>;
507
+ secondRightToPlay?: InputMaybe<Scalars['Boolean']['input']>;
508
+ withoutCompetition?: InputMaybe<Scalars['Boolean']['input']>;
509
+ sgClubId?: InputMaybe<Scalars['ID']['input']>;
510
+ }
511
+
512
+ // Bulk registration input
513
+ interface RegisterTeamsForSeasonInput {
514
+ clubId: Scalars['ID']['input'];
515
+ seasonId: Scalars['ID']['input'];
516
+ teams: Array<RegisterTeamInput>;
517
+ preferredDates?: InputMaybe<Array<InputMaybe<SavePreferredMatchdayDateInput>>>;
518
+ }
519
+
520
+ // Usage example
521
+ const newTeam: SaveTeamInput = {
522
+ clubId: 'club-123',
523
+ leagueId: 'league-456',
524
+ name: 'RV Musterhausen I',
525
+ playerIds: ['person-1', 'person-2']
526
+ };
527
+ ```
528
+
529
+ ### TeamDetail (Enhanced Team View)
530
+
531
+ ```typescript
532
+ interface TeamDetail {
533
+ __typename?: 'TeamDetail';
534
+ id: Scalars['ID']['output'];
535
+ name: Scalars['String']['output'];
536
+ club: Club;
537
+ players: Array<Maybe<Person>>;
538
+ preferredDates?: Maybe<Array<Maybe<PreferredMatchdayDate>>>;
539
+ exemptionRequest?: Maybe<Scalars['String']['output']>;
540
+ secondRightToPlay?: Maybe<Scalars['Boolean']['output']>;
541
+ withoutCompetition?: Maybe<Scalars['Boolean']['output']>;
542
+ sgClub?: Maybe<Club>;
543
+ }
544
+ ```
545
+
546
+ ### Gym
547
+
548
+ ```typescript
549
+ // Type definition
550
+ interface Gym {
551
+ __typename?: 'Gym';
552
+ id: Scalars['ID']['output'];
553
+ name: Scalars['String']['output'];
554
+ availableFields: Scalars['String']['output'];
555
+ address: Address;
556
+ club: Club;
557
+ }
558
+
559
+ // Create input
560
+ interface SaveGymInput {
561
+ clubId: Scalars['ID']['input'];
562
+ name: Scalars['String']['input'];
563
+ availableFields: Scalars['String']['input'];
564
+ address: AddressInput;
565
+ }
566
+ ```
567
+
568
+ ### Game and MatchDay
363
569
 
364
570
  ```typescript
365
571
  // Game type
366
572
  interface Game {
367
573
  __typename?: 'Game';
368
- awayScore?: Maybe<Scalars['Int']>;
369
- awayTeamId: Scalars['ID'];
370
- createdAt: Scalars['AWSDateTime'];
371
- gameNumber: Scalars['Int'];
372
- homeScore?: Maybe<Scalars['Int']>;
373
- homeTeamId: Scalars['ID'];
374
- id: Scalars['ID'];
375
- matchdayId: Scalars['ID'];
376
- refereeId?: Maybe<Scalars['ID']>;
377
- updatedAt: Scalars['AWSDateTime'];
574
+ gameNumber: Scalars['Int']['output'];
575
+ team1: MatchdayTeam;
576
+ team2: MatchdayTeam;
577
+ halftimeGoalsTeam1?: Maybe<Scalars['Int']['output']>;
578
+ halftimeGoalsTeam2?: Maybe<Scalars['Int']['output']>;
579
+ finalGoalsTeam1?: Maybe<Scalars['Int']['output']>;
580
+ finalGoalsTeam2?: Maybe<Scalars['Int']['output']>;
581
+ pointsTeam1?: Maybe<Scalars['Int']['output']>;
582
+ pointsTeam2?: Maybe<Scalars['Int']['output']>;
583
+ bothLost?: Maybe<Scalars['Boolean']['output']>;
584
+ nonCompetitive?: Maybe<Scalars['Boolean']['output']>;
585
+ }
586
+
587
+ // MatchDay type
588
+ interface MatchDay {
589
+ __typename?: 'MatchDay';
590
+ id: Scalars['ID']['output'];
591
+ matchDayNumber: Scalars['String']['output'];
592
+ startDate: Scalars['AWSDateTime']['output'];
593
+ endDate: Scalars['AWSDateTime']['output'];
594
+ group: LeagueGroup;
595
+ gym: Gym;
596
+ teams: Array<Maybe<MatchdayTeam>>;
597
+ games: Array<Maybe<Game>>;
598
+ secretary: Scalars['String']['output'];
599
+ commissioners?: Maybe<RefereeInfo>;
600
+ report?: Maybe<Scalars['String']['output']>;
601
+ reportAttachments?: Maybe<Array<Maybe<Scalars['AWSURL']['output']>>>;
602
+ streamingLink?: Maybe<Scalars['AWSURL']['output']>;
603
+ pin?: Maybe<Scalars['String']['output']>;
604
+ }
605
+
606
+ // MatchdayTeam type
607
+ interface MatchdayTeam {
608
+ __typename?: 'MatchdayTeam';
609
+ id: Scalars['ID']['output'];
610
+ team: Team;
611
+ present: Scalars['Boolean']['output'];
612
+ substitutePlayer?: Maybe<Person>;
378
613
  }
379
614
 
380
615
  // Add game input
381
616
  interface AddGameInput {
382
- awayTeamId: Scalars['ID'];
383
- gameNumber: Scalars['Int'];
384
- homeTeamId: Scalars['ID'];
385
- matchdayId: Scalars['ID'];
617
+ gameNumber: Scalars['Int']['input'];
618
+ team1Id: Scalars['ID']['input'];
619
+ team2Id: Scalars['ID']['input'];
620
+ }
621
+
622
+ // Modify game input
623
+ interface ModifyGameInput {
624
+ id: Scalars['ID']['input'];
625
+ halftimeGoalsTeam1?: InputMaybe<Scalars['Int']['input']>;
626
+ halftimeGoalsTeam2?: InputMaybe<Scalars['Int']['input']>;
627
+ finalGoalsTeam1?: InputMaybe<Scalars['Int']['input']>;
628
+ finalGoalsTeam2?: InputMaybe<Scalars['Int']['input']>;
629
+ pointsTeam1?: InputMaybe<Scalars['Int']['input']>;
630
+ pointsTeam2?: InputMaybe<Scalars['Int']['input']>;
631
+ bothLost?: InputMaybe<Scalars['Boolean']['input']>;
632
+ nonCompetitive?: InputMaybe<Scalars['Boolean']['input']>;
633
+ }
634
+ ```
635
+
636
+ ### RankingEntry
637
+
638
+ ```typescript
639
+ interface RankingEntry {
640
+ __typename?: 'RankingEntry';
641
+ rank: Scalars['Int']['output'];
642
+ team: Team;
643
+ games: Scalars['Int']['output'];
644
+ points: Scalars['Int']['output'];
645
+ goalsPlus: Scalars['Int']['output'];
646
+ goalsMinus: Scalars['Int']['output'];
647
+ goalsDiff: Scalars['Int']['output'];
648
+ }
649
+ ```
650
+
651
+ ### PreferredMatchdayDate
652
+
653
+ ```typescript
654
+ interface PreferredMatchdayDate {
655
+ __typename?: 'PreferredMatchdayDate';
656
+ preferenceDate: Scalars['AWSDate']['output'];
657
+ status: PreferenceStatus;
658
+ notes?: Maybe<Scalars['String']['output']>;
659
+ club: Club;
660
+ league: League;
661
+ season: Season;
662
+ gym?: Maybe<Gym>;
663
+ }
664
+
665
+ interface SavePreferredMatchdayDateInput {
666
+ clubId: Scalars['ID']['input'];
667
+ leagueId: Scalars['ID']['input'];
668
+ preferenceDate: Scalars['AWSDate']['input'];
669
+ status: PreferenceStatus;
670
+ notes?: InputMaybe<Scalars['String']['input']>;
671
+ gymId?: InputMaybe<Scalars['ID']['input']>;
672
+ }
673
+
674
+ // PreferenceStatus enum
675
+ enum PreferenceStatus {
676
+ Available = 'AVAILABLE',
677
+ Preferred = 'PREFERRED'
678
+ }
679
+ ```
680
+
681
+ ## Competition Types (Tournaments/Wettbewerbe)
682
+
683
+ Competitions are standalone tournaments that are NOT tied to a Season. They have their own registration periods and access control.
684
+
685
+ ### Competition
686
+
687
+ ```typescript
688
+ // Type definition
689
+ interface Competition {
690
+ __typename?: 'Competition';
691
+ id: Scalars['ID']['output'];
692
+ name: Scalars['String']['output'];
693
+ shortName: Scalars['String']['output'];
694
+ description?: Maybe<Scalars['String']['output']>;
695
+ association: Association;
696
+ startDate: Scalars['AWSDate']['output'];
697
+ endDate: Scalars['AWSDate']['output'];
698
+ registrationStart: Scalars['AWSDate']['output'];
699
+ registrationEnd: Scalars['AWSDate']['output'];
700
+ registrationPermission: RegistrationPermission;
701
+ allowedRegistrars?: Maybe<Array<Maybe<Scalars['ID']['output']>>>;
702
+ minAge?: Maybe<Scalars['Int']['output']>;
703
+ maxAge?: Maybe<Scalars['Int']['output']>;
704
+ groups?: Maybe<Array<Maybe<CompetitionGroup>>>;
705
+ coordinators?: Maybe<Array<Maybe<Person>>>;
706
+ regulationFileUrl?: Maybe<Scalars['AWSURL']['output']>;
707
+ }
708
+
709
+ // Create input
710
+ interface SaveCompetitionInput {
711
+ associationId: Scalars['ID']['input'];
712
+ name: Scalars['String']['input'];
713
+ shortName: Scalars['String']['input'];
714
+ description?: InputMaybe<Scalars['String']['input']>;
715
+ startDate: Scalars['AWSDate']['input'];
716
+ endDate: Scalars['AWSDate']['input'];
717
+ registrationStart: Scalars['AWSDate']['input'];
718
+ registrationEnd: Scalars['AWSDate']['input'];
719
+ registrationPermission?: InputMaybe<RegistrationPermission>;
720
+ allowedRegistrars?: InputMaybe<Array<InputMaybe<Scalars['ID']['input']>>>;
721
+ minAge?: InputMaybe<Scalars['Int']['input']>;
722
+ maxAge?: InputMaybe<Scalars['Int']['input']>;
723
+ coordinatorIds?: InputMaybe<Array<InputMaybe<Scalars['ID']['input']>>>;
724
+ regulationFileUrl?: InputMaybe<Scalars['AWSURL']['input']>;
725
+ }
726
+
727
+ // Update input
728
+ interface ModifyCompetitionInput {
729
+ id: Scalars['ID']['input'];
730
+ name?: InputMaybe<Scalars['String']['input']>;
731
+ shortName?: InputMaybe<Scalars['String']['input']>;
732
+ description?: InputMaybe<Scalars['String']['input']>;
733
+ startDate?: InputMaybe<Scalars['AWSDate']['input']>;
734
+ endDate?: InputMaybe<Scalars['AWSDate']['input']>;
735
+ registrationStart?: InputMaybe<Scalars['AWSDate']['input']>;
736
+ registrationEnd?: InputMaybe<Scalars['AWSDate']['input']>;
737
+ registrationPermission?: InputMaybe<RegistrationPermission>;
738
+ allowedRegistrars?: InputMaybe<Array<InputMaybe<Scalars['ID']['input']>>>;
739
+ minAge?: InputMaybe<Scalars['Int']['input']>;
740
+ maxAge?: InputMaybe<Scalars['Int']['input']>;
741
+ coordinatorIds?: InputMaybe<Array<InputMaybe<Scalars['ID']['input']>>>;
742
+ regulationFileUrl?: InputMaybe<Scalars['AWSURL']['input']>;
743
+ }
744
+
745
+ // RegistrationPermission enum - Controls who can register for a competition
746
+ enum RegistrationPermission {
747
+ AllClubs = 'ALL_CLUBS', // Any club can register
748
+ AssociationsOnly = 'ASSOCIATIONS_ONLY', // Only associations can register teams
749
+ InviteOnly = 'INVITE_ONLY' // Only specifically allowed registrars
750
+ }
751
+
752
+ // Usage example
753
+ const newCompetition: SaveCompetitionInput = {
754
+ associationId: 'association-123',
755
+ name: 'Deutsche Meisterschaft 2024',
756
+ shortName: 'DM2024',
757
+ description: 'Jährliche Deutsche Meisterschaft im Radball',
758
+ startDate: '2024-06-01',
759
+ endDate: '2024-06-02',
760
+ registrationStart: '2024-03-01',
761
+ registrationEnd: '2024-05-15',
762
+ registrationPermission: RegistrationPermission.AssociationsOnly
763
+ };
764
+ ```
765
+
766
+ ### CompetitionGroup
767
+
768
+ ```typescript
769
+ // Type definition
770
+ interface CompetitionGroup {
771
+ __typename?: 'CompetitionGroup';
772
+ id: Scalars['ID']['output'];
773
+ name: Scalars['String']['output'];
774
+ shortName: Scalars['String']['output'];
775
+ number: Scalars['Int']['output'];
776
+ regulation: Scalars['String']['output'];
777
+ competition: Competition;
778
+ association: Association;
779
+ leader?: Maybe<Person>;
780
+ teams?: Maybe<Array<Maybe<CompetitionTeam>>>;
781
+ }
782
+
783
+ // Create input
784
+ interface SaveCompetitionGroupInput {
785
+ competitionId: Scalars['ID']['input'];
786
+ name: Scalars['String']['input'];
787
+ shortName: Scalars['String']['input'];
788
+ number: Scalars['Int']['input'];
789
+ regulation: Scalars['String']['input'];
790
+ leaderId?: InputMaybe<Scalars['ID']['input']>;
791
+ }
792
+
793
+ // Update input
794
+ interface ModifyCompetitionGroupInput {
795
+ id: Scalars['ID']['input'];
796
+ name?: InputMaybe<Scalars['String']['input']>;
797
+ shortName?: InputMaybe<Scalars['String']['input']>;
798
+ number?: InputMaybe<Scalars['Int']['input']>;
799
+ regulation?: InputMaybe<Scalars['String']['input']>;
800
+ leaderId?: InputMaybe<Scalars['ID']['input']>;
801
+ }
802
+ ```
803
+
804
+ ### CompetitionTeam
805
+
806
+ ```typescript
807
+ // Type definition
808
+ interface CompetitionTeam {
809
+ __typename?: 'CompetitionTeam';
810
+ id: Scalars['ID']['output'];
811
+ name: Scalars['String']['output'];
812
+ club: Club;
813
+ competition: Competition;
814
+ competitionGroup?: Maybe<CompetitionGroup>;
815
+ players: Array<Maybe<Person>>;
816
+ exemptionRequest?: Maybe<Scalars['String']['output']>;
817
+ secondRightToPlay?: Maybe<Scalars['Boolean']['output']>;
818
+ withoutCompetition?: Maybe<Scalars['Boolean']['output']>;
819
+ sgClub?: Maybe<Club>;
820
+ }
821
+
822
+ // Create input
823
+ interface SaveCompetitionTeamInput {
824
+ competitionId: Scalars['ID']['input'];
825
+ competitionGroupId?: InputMaybe<Scalars['ID']['input']>;
826
+ clubId: Scalars['ID']['input'];
827
+ name: Scalars['String']['input'];
828
+ playerIds: Array<Scalars['ID']['input']>;
829
+ exemptionRequest?: InputMaybe<Scalars['String']['input']>;
830
+ secondRightToPlay?: InputMaybe<Scalars['Boolean']['input']>;
831
+ withoutCompetition?: InputMaybe<Scalars['Boolean']['input']>;
832
+ sgClubId?: InputMaybe<Scalars['ID']['input']>;
833
+ }
834
+
835
+ // Update input
836
+ interface ModifyCompetitionTeamInput {
837
+ id: Scalars['ID']['input'];
838
+ name?: InputMaybe<Scalars['String']['input']>;
839
+ competitionGroupId?: InputMaybe<Scalars['ID']['input']>;
840
+ playerIds?: InputMaybe<Array<InputMaybe<Scalars['ID']['input']>>>;
841
+ exemptionRequest?: InputMaybe<Scalars['String']['input']>;
842
+ secondRightToPlay?: InputMaybe<Scalars['Boolean']['input']>;
843
+ withoutCompetition?: InputMaybe<Scalars['Boolean']['input']>;
844
+ sgClubId?: InputMaybe<Scalars['ID']['input']>;
845
+ }
846
+
847
+ // Register single team input
848
+ interface RegisterCompetitionTeamInput {
849
+ clubId: Scalars['ID']['input'];
850
+ competitionGroupId?: InputMaybe<Scalars['ID']['input']>;
851
+ name: Scalars['String']['input'];
852
+ playerIds: Array<Scalars['ID']['input']>;
853
+ exemptionRequest?: InputMaybe<Scalars['String']['input']>;
854
+ secondRightToPlay?: InputMaybe<Scalars['Boolean']['input']>;
855
+ withoutCompetition?: InputMaybe<Scalars['Boolean']['input']>;
856
+ sgClubId?: InputMaybe<Scalars['ID']['input']>;
857
+ }
858
+
859
+ // Bulk registration input (for federations registering multiple teams)
860
+ interface RegisterCompetitionTeamsInput {
861
+ competitionId: Scalars['ID']['input'];
862
+ registrarClubId: Scalars['ID']['input'];
863
+ registrarPersonId: Scalars['ID']['input'];
864
+ teams: Array<RegisterCompetitionTeamInput>;
865
+ }
866
+ ```
867
+
868
+ ### Competition Registration Result
869
+
870
+ ```typescript
871
+ // Bulk registration result
872
+ interface CompetitionRegistrationResult {
873
+ __typename?: 'CompetitionRegistrationResult';
874
+ success: Scalars['Boolean']['output'];
875
+ registeredTeams: Array<Maybe<CompetitionTeam>>;
876
+ errors: Array<Maybe<CompetitionRegistrationError>>;
877
+ }
878
+
879
+ interface CompetitionRegistrationError {
880
+ __typename?: 'CompetitionRegistrationError';
881
+ errorCode: Scalars['String']['output'];
882
+ message: Scalars['String']['output'];
883
+ teamName: Scalars['String']['output'];
884
+ clubId?: Maybe<Scalars['ID']['output']>;
885
+ }
886
+
887
+ // Registration eligibility check
888
+ interface RegistrationEligibility {
889
+ __typename?: 'RegistrationEligibility';
890
+ canRegister: Scalars['Boolean']['output'];
891
+ registrationOpen: Scalars['Boolean']['output'];
892
+ registrationEnds?: Maybe<Scalars['AWSDate']['output']>;
893
+ reason?: Maybe<Scalars['String']['output']>;
894
+ }
895
+ ```
896
+
897
+ ### CompetitionGroupView
898
+
899
+ ```typescript
900
+ interface CompetitionGroupView {
901
+ __typename?: 'CompetitionGroupView';
902
+ competitionGroup: CompetitionGroup;
903
+ teams: Array<Maybe<TeamDetail>>;
904
+ clubs: Array<Maybe<Club>>;
905
+ gyms: Array<Maybe<Gym>>;
906
+ statistics?: Maybe<CompetitionGroupStatistics>;
907
+ }
908
+
909
+ interface CompetitionGroupStatistics {
910
+ __typename?: 'CompetitionGroupStatistics';
911
+ totalTeams: Scalars['Int']['output'];
912
+ totalPlayers: Scalars['Int']['output'];
913
+ totalClubs: Scalars['Int']['output'];
914
+ totalGyms: Scalars['Int']['output'];
915
+ }
916
+ ```
917
+
918
+ ## View Types
919
+
920
+ ### LeagueGroupView
921
+
922
+ ```typescript
923
+ interface LeagueGroupView {
924
+ __typename?: 'LeagueGroupView';
925
+ group: LeagueGroup;
926
+ teams: Array<Maybe<TeamDetail>>;
927
+ clubs: Array<Maybe<Club>>;
928
+ gyms: Array<Maybe<Gym>>;
929
+ statistics?: Maybe<LeagueGroupStatistics>;
930
+ }
931
+
932
+ interface LeagueGroupStatistics {
933
+ __typename?: 'LeagueGroupStatistics';
934
+ totalTeams: Scalars['Int']['output'];
935
+ totalPlayers: Scalars['Int']['output'];
936
+ totalClubs: Scalars['Int']['output'];
937
+ totalGyms: Scalars['Int']['output'];
386
938
  }
387
939
  ```
388
940
 
@@ -390,47 +942,82 @@ interface AddGameInput {
390
942
 
391
943
  ### Using Check Functions (Non-throwing)
392
944
 
945
+ Check functions validate input and return a `ValidationCheckResult` object with errors and warnings.
946
+
393
947
  ```typescript
394
- import { checkClub, checkPerson, ValidationCheckResult } from '@taimos/radball-digital-api';
948
+ import {
949
+ checkClub,
950
+ checkPerson,
951
+ checkSeason,
952
+ checkLeague,
953
+ checkLeagueGroup,
954
+ checkTeam,
955
+ checkGym,
956
+ checkAddress,
957
+ checkAssociation,
958
+ ValidationCheckResult
959
+ } from '@taimos/radball-digital-api';
395
960
 
396
961
  // Check functions return ValidationCheckResult
397
962
  const clubData: SaveClubInput = {
398
963
  associationId: 'assoc-123',
399
964
  name: '', // Invalid - empty name
400
- shortName: 'ABC'
965
+ shortName: 'ABC',
966
+ contactId: 'person-123',
967
+ address: { city: 'Berlin', country: 'DE', street: 'Hauptstr. 1', zip: '12345' }
401
968
  };
402
969
 
403
970
  const result = checkClub(clubData);
404
- if (result.hasErrors()) {
971
+ if (Object.keys(result.errors).length > 0) {
405
972
  console.error('Validation errors:', result.errors);
406
- // Output: { name: ['Name ist erforderlich'] }
973
+ // Output: { name: ['Vereinsname ist erforderlich'] }
407
974
  }
408
975
 
409
976
  // Check with warnings
410
977
  const personData: SavePersonInput = {
411
- firstname: 'John',
412
- lastname: 'Doe',
978
+ clubId: 'club-123',
979
+ firstName: 'John',
980
+ lastName: 'Doe',
413
981
  email: 'invalid-email' // Invalid email format
414
982
  };
415
983
 
416
984
  const personResult = checkPerson(personData);
417
- if (personResult.hasErrors() || personResult.hasWarnings()) {
985
+ if (Object.keys(personResult.errors).length > 0) {
418
986
  console.log('Errors:', personResult.errors);
419
- console.log('Warnings:', personResult.warnings);
987
+ console.log('Error messages:', personResult.getErrorMessagesString());
988
+ }
989
+ ```
990
+
991
+ ### ValidationCheckResult Class
992
+
993
+ ```typescript
994
+ class ValidationCheckResult {
995
+ public readonly warnings: { [field: string]: string[] } = {};
996
+ public readonly errors: { [field: string]: string[] } = {};
997
+
998
+ public addWarning(field: string, message: string): void;
999
+ public addError(field: string, message: string): void;
1000
+ public getErrorMessages(): string[];
1001
+ public getWarningMessages(): string[];
1002
+ public getErrorMessagesString(): string;
1003
+ public getWarningMessagesString(): string;
1004
+ public validate(): void; // Throws if errors exist
420
1005
  }
421
1006
  ```
422
1007
 
423
1008
  ### Using Validate Functions (Throwing)
424
1009
 
1010
+ Validate functions throw an error if validation fails.
1011
+
425
1012
  ```typescript
426
- import { validateTeam, validateSeason } from '@taimos/radball-digital-api';
1013
+ import { validateTeam, validateSeason, validateClub } from '@taimos/radball-digital-api';
427
1014
 
428
1015
  // Validate functions throw on error
429
1016
  const teamData: SaveTeamInput = {
430
1017
  clubId: 'club-123',
1018
+ leagueId: 'league-456',
431
1019
  name: 'Team A',
432
- discipline: 'RADBALL',
433
- status: 'ACTIVE'
1020
+ playerIds: ['person-1', 'person-2']
434
1021
  };
435
1022
 
436
1023
  try {
@@ -447,61 +1034,59 @@ const seasonData: SaveSeasonInput = {
447
1034
  name: 'Season 2024',
448
1035
  startDate: '2024-09-01',
449
1036
  endDate: '2024-06-01', // Invalid - end before start
450
- registrationStartDate: '2024-07-01',
451
- registrationEndDate: '2024-08-15'
1037
+ registrationEnd: '2024-08-15',
1038
+ additionalEligibleAssociations: []
452
1039
  };
453
1040
 
454
1041
  try {
455
1042
  validateSeason(seasonData);
456
1043
  } catch (error) {
457
- // Will throw: "Enddatum muss nach dem Startdatum liegen"
1044
+ // Will throw: "Saison-Enddatum muss nach dem Startdatum liegen"
458
1045
  console.error(error.message);
459
1046
  }
460
1047
  ```
461
1048
 
462
- ### Custom Validation Workflow
1049
+ ### Season Registration Check
463
1050
 
464
1051
  ```typescript
465
- import { ValidationCheckResult } from '@taimos/radball-digital-api';
1052
+ import { isSeasonOpenForRegistration } from '@taimos/radball-digital-api';
466
1053
 
467
- // Create custom validation workflow
468
- function validateGameData(game: AddGameInput): ValidationCheckResult {
469
- const result = new ValidationCheckResult();
470
-
471
- // Basic validation
472
- if (!game.homeTeamId) {
473
- result.addError('homeTeamId', 'Heimmannschaft ist erforderlich');
474
- }
475
-
476
- if (!game.awayTeamId) {
477
- result.addError('awayTeamId', 'Gastmannschaft ist erforderlich');
478
- }
479
-
480
- // Business logic validation
481
- if (game.homeTeamId === game.awayTeamId) {
482
- result.addError('teams', 'Heim- und Gastmannschaft müssen unterschiedlich sein');
483
- }
484
-
485
- if (game.gameNumber < 1) {
486
- result.addError('gameNumber', 'Spielnummer muss größer als 0 sein');
487
- }
488
-
489
- return result;
490
- }
491
-
492
- // Usage
493
- const gameInput: AddGameInput = {
494
- homeTeamId: 'team-1',
495
- awayTeamId: 'team-1', // Same as home
496
- gameNumber: 0, // Invalid
497
- matchdayId: 'matchday-123'
1054
+ // Check if registration is currently open
1055
+ const season: SaveSeasonInput = {
1056
+ associationId: 'assoc-123',
1057
+ name: 'Season 2024/2025',
1058
+ startDate: '2024-09-01',
1059
+ endDate: '2025-06-30',
1060
+ registrationStart: '2024-07-01',
1061
+ registrationEnd: '2024-08-15',
1062
+ additionalEligibleAssociations: []
498
1063
  };
499
1064
 
500
- const validation = validateGameData(gameInput);
501
- if (validation.hasErrors()) {
502
- // Throw aggregated error
503
- validation.throwIfErrors();
504
- }
1065
+ const today = '2024-07-15';
1066
+ const isOpen = isSeasonOpenForRegistration(season, today);
1067
+ console.log('Registration open:', isOpen); // true
1068
+ ```
1069
+
1070
+ ### Available Validation Functions
1071
+
1072
+ | Entity | Check Function | Validate Function |
1073
+ |--------|----------------|-------------------|
1074
+ | Address | `checkAddress(address)` | `validateAddress(address)` |
1075
+ | Association | `checkAssociation(association)` | `validateAssociation(association)` |
1076
+ | Club | `checkClub(club)` | `validateClub(club)` |
1077
+ | Gym | `checkGym(gym)` | `validateGym(gym)` |
1078
+ | League | `checkLeague(league)` | `validateLeague(league)` |
1079
+ | LeagueGroup | `checkLeagueGroup(leagueGroup)` | `validateLeagueGroup(leagueGroup)` |
1080
+ | Person | `checkPerson(person)` | `validatePerson(person)` |
1081
+ | Season | `checkSeason(season)` | `validateSeason(season)` |
1082
+ | Team | `checkTeam(team)` | `validateTeam(team)` |
1083
+
1084
+ ### Email Validation Regex
1085
+
1086
+ ```typescript
1087
+ import { REGEX_EMAIL_FORMAT } from '@taimos/radball-digital-api';
1088
+
1089
+ const isValidEmail = REGEX_EMAIL_FORMAT.test('user@example.com'); // true
505
1090
  ```
506
1091
 
507
1092
  ## GraphQL Operations
@@ -510,7 +1095,12 @@ if (validation.hasErrors()) {
510
1095
 
511
1096
  ```typescript
512
1097
  // Type-safe query arguments
513
- import { QueryGetClubByIdArgs, QueryListClubsArgs } from '@taimos/radball-digital-api';
1098
+ import {
1099
+ QueryGetClubByIdArgs,
1100
+ QueryGetListOfClubsArgs,
1101
+ QueryGetCompetitionByIdArgs,
1102
+ QueryCanClubRegisterForCompetitionArgs
1103
+ } from '@taimos/radball-digital-api';
514
1104
 
515
1105
  // Single club query
516
1106
  const getClubArgs: QueryGetClubByIdArgs = {
@@ -518,17 +1108,20 @@ const getClubArgs: QueryGetClubByIdArgs = {
518
1108
  };
519
1109
 
520
1110
  // List clubs with pagination
521
- const listClubsArgs: QueryListClubsArgs = {
522
- associationId: 'assoc-123',
1111
+ const listClubsArgs: QueryGetListOfClubsArgs = {
523
1112
  limit: 20,
524
1113
  nextToken: undefined // For pagination
525
1114
  };
526
1115
 
527
- // Complex query with filters
528
- const listTeamsArgs = {
1116
+ // Get competition
1117
+ const getCompetitionArgs: QueryGetCompetitionByIdArgs = {
1118
+ id: 'competition-123'
1119
+ };
1120
+
1121
+ // Check registration eligibility
1122
+ const canRegisterArgs: QueryCanClubRegisterForCompetitionArgs = {
529
1123
  clubId: 'club-123',
530
- discipline: 'RADBALL',
531
- status: 'ACTIVE'
1124
+ competitionId: 'competition-456'
532
1125
  };
533
1126
  ```
534
1127
 
@@ -536,77 +1129,97 @@ const listTeamsArgs = {
536
1129
 
537
1130
  ```typescript
538
1131
  // Type-safe mutation arguments
539
- import {
1132
+ import {
540
1133
  MutationAddClubArgs,
541
- MutationRegisterTeamArgs,
542
- MutationAddGameArgs
1134
+ MutationRegisterTeamsForSeasonArgs,
1135
+ MutationAddGameToMatchDayArgs,
1136
+ MutationAddCompetitionArgs,
1137
+ MutationRegisterCompetitionTeamsArgs
543
1138
  } from '@taimos/radball-digital-api';
544
1139
 
545
1140
  // Add club mutation
546
1141
  const addClubArgs: MutationAddClubArgs = {
547
- input: {
1142
+ club: {
548
1143
  associationId: 'assoc-123',
549
1144
  name: 'New Club',
550
- shortName: 'NC'
1145
+ shortName: 'NC',
1146
+ contactId: 'person-123',
1147
+ address: {
1148
+ street: 'Hauptstr. 1',
1149
+ zip: '12345',
1150
+ city: 'Berlin',
1151
+ country: 'DE'
1152
+ }
551
1153
  }
552
1154
  };
553
1155
 
554
- // Register team for season
555
- const registerTeamArgs: MutationRegisterTeamArgs = {
556
- input: {
557
- teamId: 'team-123',
558
- leagueGroupId: 'group-456',
559
- players: ['person-1', 'person-2'],
560
- preferredMatchdayDates: [
1156
+ // Register teams for season
1157
+ const registerTeamsArgs: MutationRegisterTeamsForSeasonArgs = {
1158
+ registration: {
1159
+ clubId: 'club-123',
1160
+ seasonId: 'season-456',
1161
+ teams: [
561
1162
  {
562
- date: '2024-10-15',
563
- status: 'PREFERRED'
564
- },
1163
+ leagueId: 'league-789',
1164
+ name: 'RV Musterhausen I',
1165
+ playerIds: ['person-1', 'person-2']
1166
+ }
1167
+ ],
1168
+ preferredDates: [
565
1169
  {
566
- date: '2024-10-22',
567
- status: 'NOT_POSSIBLE'
1170
+ clubId: 'club-123',
1171
+ leagueId: 'league-789',
1172
+ preferenceDate: '2024-10-15',
1173
+ status: PreferenceStatus.Preferred
568
1174
  }
569
1175
  ]
570
1176
  }
571
1177
  };
572
1178
 
573
1179
  // Add game to matchday
574
- const addGameArgs: MutationAddGameArgs = {
575
- input: {
576
- matchdayId: 'matchday-123',
577
- homeTeamId: 'team-1',
578
- awayTeamId: 'team-2',
579
- gameNumber: 1
1180
+ const addGameArgs: MutationAddGameToMatchDayArgs = {
1181
+ matchDayId: 'matchday-123',
1182
+ game: {
1183
+ gameNumber: 1,
1184
+ team1Id: 'matchdayteam-1',
1185
+ team2Id: 'matchdayteam-2'
580
1186
  }
581
1187
  };
582
- ```
583
-
584
- ## REST API Usage
585
-
586
- ### Import Endpoints
587
-
588
- ```typescript
589
- import { paths, operations } from '@taimos/radball-digital-api';
590
-
591
- // Type definitions for import endpoints
592
- type ClubImportRequest = paths['/import/clubs']['post']['requestBody']['content']['text/plain'];
593
- type ClubImportResponse = paths['/import/clubs']['post']['responses']['200']['content']['application/json'];
594
-
595
- type GymImportRequest = paths['/import/gyms']['post']['requestBody']['content']['text/plain'];
596
- type PersonImportRequest = paths['/import/persons']['post']['requestBody']['content']['text/csv'];
597
1188
 
598
- // Example: Import clubs from fixed-width text
599
- const clubsText = `
600
- 001 RV Musterhausen RVM
601
- 002 SC Example SCE
602
- `;
1189
+ // Add competition
1190
+ const addCompetitionArgs: MutationAddCompetitionArgs = {
1191
+ competition: {
1192
+ associationId: 'assoc-123',
1193
+ name: 'Deutsche Meisterschaft 2024',
1194
+ shortName: 'DM2024',
1195
+ startDate: '2024-06-01',
1196
+ endDate: '2024-06-02',
1197
+ registrationStart: '2024-03-01',
1198
+ registrationEnd: '2024-05-15',
1199
+ registrationPermission: RegistrationPermission.AssociationsOnly
1200
+ }
1201
+ };
603
1202
 
604
- // Example: Import persons from CSV
605
- const personsCsv = `
606
- firstname,lastname,email,birthdate,clubId
607
- Max,Mustermann,max@example.com,1990-01-15,club-123
608
- Anna,Schmidt,anna@example.com,1992-03-20,club-456
609
- `;
1203
+ // Bulk register teams for competition (federation use case)
1204
+ const registerCompetitionTeamsArgs: MutationRegisterCompetitionTeamsArgs = {
1205
+ registration: {
1206
+ competitionId: 'competition-123',
1207
+ registrarClubId: 'association-club-id',
1208
+ registrarPersonId: 'registrar-person-id',
1209
+ teams: [
1210
+ {
1211
+ clubId: 'club-1',
1212
+ name: 'RV Club 1 I',
1213
+ playerIds: ['person-1', 'person-2']
1214
+ },
1215
+ {
1216
+ clubId: 'club-2',
1217
+ name: 'RV Club 2 I',
1218
+ playerIds: ['person-3', 'person-4']
1219
+ }
1220
+ ]
1221
+ }
1222
+ };
610
1223
  ```
611
1224
 
612
1225
  ## Common Patterns
@@ -616,21 +1229,21 @@ Anna,Schmidt,anna@example.com,1992-03-20,club-456
616
1229
  ```typescript
617
1230
  // Using Maybe types
618
1231
  function getPersonFullName(person: Person): string {
619
- const first = person.firstname ?? '';
620
- const last = person.lastname ?? '';
1232
+ const first = person.firstName ?? '';
1233
+ const last = person.lastName ?? '';
621
1234
  return `${first} ${last}`.trim() || 'Unknown';
622
1235
  }
623
1236
 
624
1237
  // Handling optional addresses
625
1238
  function formatAddress(address: Maybe<Address>): string {
626
1239
  if (!address) return 'No address';
627
-
1240
+
628
1241
  const parts = [
629
- address.street && address.number ? `${address.street} ${address.number}` : '',
1242
+ address.street,
630
1243
  address.zip && address.city ? `${address.zip} ${address.city}` : '',
631
1244
  address.country
632
1245
  ].filter(Boolean);
633
-
1246
+
634
1247
  return parts.join(', ') || 'Incomplete address';
635
1248
  }
636
1249
  ```
@@ -646,21 +1259,18 @@ function isSeasonActive(season: Season): boolean {
646
1259
 
647
1260
  // Registration period check
648
1261
  function isRegistrationOpen(season: Season): boolean {
649
- if (!season.registrationStartDate || !season.registrationEndDate) {
1262
+ if (!season.registrationStart || !season.registrationEnd) {
650
1263
  return false;
651
1264
  }
652
-
1265
+
653
1266
  const today = new Date().toISOString().split('T')[0];
654
- return season.registrationStartDate <= today && today <= season.registrationEndDate;
1267
+ return season.registrationStart <= today && today <= season.registrationEnd;
655
1268
  }
656
1269
 
657
- // Age validation
658
- function canPlayerRegister(person: Person, season: Season): boolean {
659
- if (!person.birthdate || !season.minimumAgePlayerDate) {
660
- return true; // No age restriction
661
- }
662
-
663
- return person.birthdate <= season.minimumAgePlayerDate;
1270
+ // Competition registration check
1271
+ function isCompetitionRegistrationOpen(competition: Competition): boolean {
1272
+ const today = new Date().toISOString().split('T')[0];
1273
+ return competition.registrationStart <= today && today <= competition.registrationEnd;
664
1274
  }
665
1275
  ```
666
1276
 
@@ -674,85 +1284,31 @@ async function createClub(input: SaveClubInput): Promise<Club | { errors: Record
674
1284
  try {
675
1285
  // Validate input
676
1286
  validateClub(input);
677
-
1287
+
678
1288
  // Make API call (pseudo-code)
679
1289
  const result = await apiClient.mutation({
680
1290
  addClub: {
681
- input
1291
+ club: input
682
1292
  }
683
1293
  });
684
-
1294
+
685
1295
  return result.addClub;
686
1296
  } catch (error) {
687
- if (error.message.includes('Validierung fehlgeschlagen')) {
1297
+ if (error.message) {
688
1298
  // Parse validation errors
689
- const errors = parseValidationErrors(error.message);
690
- return { errors };
1299
+ return { errors: { validation: [error.message] } };
691
1300
  }
692
-
1301
+
693
1302
  // Re-throw other errors
694
1303
  throw error;
695
1304
  }
696
1305
  }
697
-
698
- function parseValidationErrors(message: string): Record<string, string[]> {
699
- // Extract field errors from German validation messages
700
- const errors: Record<string, string[]> = {};
701
- const lines = message.split('\n');
702
-
703
- for (const line of lines) {
704
- const match = line.match(/^(\w+): (.+)$/);
705
- if (match) {
706
- const [, field, error] = match;
707
- if (!errors[field]) errors[field] = [];
708
- errors[field].push(error);
709
- }
710
- }
711
-
712
- return errors;
713
- }
714
1306
  ```
715
1307
 
716
1308
  ### League Group Manager View
717
1309
 
718
1310
  ```typescript
719
- // League Group View types for comprehensive group management
720
- interface LeagueGroupView {
721
- __typename?: 'LeagueGroupView';
722
- group: LeagueGroup;
723
- teams: TeamDetail[];
724
- clubs: Club[];
725
- gyms: Gym[];
726
- statistics: LeagueGroupStatistics;
727
- }
728
-
729
- interface TeamDetail {
730
- __typename?: 'TeamDetail';
731
- id: Scalars['ID'];
732
- club: Club;
733
- name: Scalars['String'];
734
- players: Person[];
735
- withoutCompetition?: Maybe<Scalars['Boolean']>;
736
- secondRightToPlay?: Maybe<Scalars['Boolean']>;
737
- sgClub?: Maybe<Club>;
738
- exemptionRequest?: Maybe<Scalars['String']>;
739
- preferredDates?: Maybe<PreferredMatchdayDate[]>;
740
- }
741
-
742
- interface LeagueGroupStatistics {
743
- __typename?: 'LeagueGroupStatistics';
744
- totalTeams: Scalars['Int'];
745
- totalPlayers: Scalars['Int'];
746
- totalClubs: Scalars['Int'];
747
- totalGyms: Scalars['Int'];
748
- }
749
-
750
1311
  // Query for league group manager
751
- const getLeagueGroupViewArgs = {
752
- groupId: 'group-123'
753
- };
754
-
755
- // Usage example
756
1312
  async function exportLeagueGroupData(groupId: string): Promise<void> {
757
1313
  const groupView = await apiClient.query({
758
1314
  getLeagueGroupView: {
@@ -771,85 +1327,144 @@ async function exportLeagueGroupData(groupId: string): Promise<void> {
771
1327
 
772
1328
  // Export statistics
773
1329
  const stats = groupView.statistics;
774
- console.log(`Total Teams: ${stats.totalTeams}`);
775
- console.log(`Total Players: ${stats.totalPlayers}`);
776
- console.log(`Total Clubs: ${stats.totalClubs}`);
777
- console.log(`Total Gyms: ${stats.totalGyms}`);
1330
+ console.log(`Total Teams: ${stats?.totalTeams}`);
1331
+ console.log(`Total Players: ${stats?.totalPlayers}`);
1332
+ console.log(`Total Clubs: ${stats?.totalClubs}`);
1333
+ console.log(`Total Gyms: ${stats?.totalGyms}`);
1334
+ }
1335
+ ```
1336
+
1337
+ ### Competition Registration Workflow
1338
+
1339
+ ```typescript
1340
+ // Check if club can register for competition
1341
+ async function checkAndRegisterForCompetition(
1342
+ clubId: string,
1343
+ competitionId: string,
1344
+ teams: RegisterCompetitionTeamInput[]
1345
+ ): Promise<CompetitionRegistrationResult> {
1346
+ // First, check eligibility
1347
+ const eligibility = await apiClient.query({
1348
+ canClubRegisterForCompetition: {
1349
+ clubId,
1350
+ competitionId
1351
+ }
1352
+ });
1353
+
1354
+ if (!eligibility.canRegister) {
1355
+ throw new Error(`Registration not allowed: ${eligibility.reason}`);
1356
+ }
1357
+
1358
+ if (!eligibility.registrationOpen) {
1359
+ throw new Error('Registration period is closed');
1360
+ }
1361
+
1362
+ // Proceed with registration
1363
+ const result = await apiClient.mutation({
1364
+ registerCompetitionTeams: {
1365
+ registration: {
1366
+ competitionId,
1367
+ registrarClubId: clubId,
1368
+ registrarPersonId: 'current-user-id',
1369
+ teams
1370
+ }
1371
+ }
1372
+ });
1373
+
1374
+ if (!result.success) {
1375
+ console.error('Some registrations failed:', result.errors);
1376
+ }
1377
+
1378
+ return result;
778
1379
  }
779
1380
  ```
780
1381
 
781
1382
  ### Batch Operations
782
1383
 
783
1384
  ```typescript
784
- // Register multiple teams
1385
+ // Register multiple teams for a season
785
1386
  async function registerTeamsForSeason(
1387
+ clubId: string,
786
1388
  seasonId: string,
787
- registrations: Array<{ teamId: string; leagueGroupId: string; players: string[] }>
788
- ): Promise<void> {
1389
+ registrations: Array<{ leagueId: string; name: string; playerIds: string[] }>
1390
+ ): Promise<Team[]> {
789
1391
  // Validate all registrations first
790
- const validationResults = registrations.map(reg => {
791
- const result = new ValidationCheckResult();
792
-
793
- if (!reg.teamId) result.addError('teamId', 'Team ist erforderlich');
794
- if (!reg.leagueGroupId) result.addError('leagueGroupId', 'Liga-Gruppe ist erforderlich');
795
- if (!reg.players || reg.players.length < 2) {
796
- result.addError('players', 'Mindestens 2 Spieler erforderlich');
1392
+ for (const reg of registrations) {
1393
+ const result = checkTeam({
1394
+ clubId,
1395
+ leagueId: reg.leagueId,
1396
+ name: reg.name,
1397
+ playerIds: reg.playerIds
1398
+ });
1399
+
1400
+ if (Object.keys(result.errors).length > 0) {
1401
+ throw new Error(`Validation failed for ${reg.name}: ${result.getErrorMessagesString()}`);
797
1402
  }
798
-
799
- return { registration: reg, validation: result };
800
- });
801
-
802
- // Check for validation errors
803
- const errors = validationResults.filter(r => r.validation.hasErrors());
804
- if (errors.length > 0) {
805
- throw new Error(`${errors.length} Registrierungen sind ungültig`);
806
1403
  }
807
-
808
- // Process valid registrations
809
- for (const { registration } of validationResults) {
810
- await apiClient.mutation({
811
- registerTeam: {
812
- input: {
813
- teamId: registration.teamId,
814
- leagueGroupId: registration.leagueGroupId,
815
- players: registration.players
816
- }
1404
+
1405
+ // Process registrations
1406
+ const response = await apiClient.mutation({
1407
+ registerTeamsForSeason: {
1408
+ registration: {
1409
+ clubId,
1410
+ seasonId,
1411
+ teams: registrations.map(reg => ({
1412
+ leagueId: reg.leagueId,
1413
+ name: reg.name,
1414
+ playerIds: reg.playerIds
1415
+ }))
817
1416
  }
818
- });
819
- }
1417
+ }
1418
+ });
1419
+
1420
+ return response.registerTeamsForSeason ?? [];
820
1421
  }
821
1422
  ```
822
1423
 
823
1424
  ## Best Practices
824
1425
 
825
- 1. **Always validate input data** before sending to the API
826
- 2. **Use TypeScript types** for type safety
1426
+ 1. **Always validate input data** before sending to the API using check or validate functions
1427
+ 2. **Use TypeScript types** for type safety and autocompletion
827
1428
  3. **Handle nullable fields** appropriately with Maybe types
828
- 4. **Check date ranges** for seasons and registration periods
829
- 5. **Validate business rules** (e.g., team can't play against itself)
1429
+ 4. **Check date ranges** for seasons, competitions, and registration periods
1430
+ 5. **Validate business rules** (e.g., team must have at least 2 players)
830
1431
  6. **Use German error messages** as the system is designed for German users
831
1432
  7. **Batch operations** when possible to reduce API calls
832
- 8. **Cache frequently accessed data** like associations and clubs
1433
+ 8. **Check registration eligibility** before attempting competition registrations
1434
+ 9. **Handle pagination** for large lists using nextToken
833
1435
 
834
1436
  ## Common Validation Rules
835
1437
 
836
- - **Names**: Required, max 255 characters
837
- - **Short names**: Optional, max 50 characters
838
- - **Emails**: Must be valid email format
839
- - **Dates**: Must be in YYYY-MM-DD format
1438
+ - **Names**: Required, max 100 characters
1439
+ - **Short names**: Max 10-30 characters, alphanumeric only for some entities
1440
+ - **Emails**: Must match email format regex
1441
+ - **Dates**: Must be in YYYY-MM-DD format (AWSDate)
840
1442
  - **Season dates**: End date must be after start date
841
- - **Registration dates**: Must be within season dates
842
- - **Age restrictions**: Players must meet minimum age requirements
1443
+ - **Registration dates**: Must be before season/competition start date
1444
+ - **Age restrictions**: minAge must be less than maxAge
843
1445
  - **Team composition**: Minimum 2 players required
844
- - **Unique constraints**: External IDs and legacy IDs must be unique
1446
+ - **Address fields**: Max 200 characters for street/city, 20 for zip/country
845
1447
 
846
1448
  ## Error Messages (German)
847
1449
 
848
1450
  All validation error messages are in German. Common messages:
849
1451
 
850
1452
  - "Name ist erforderlich" - Name is required
851
- - "Enddatum muss nach dem Startdatum liegen" - End date must be after start date
1453
+ - "Vereinsname ist erforderlich" - Club name is required
1454
+ - "Verbandsname ist erforderlich" - Association name is required
1455
+ - "Saisonname ist erforderlich" - Season name is required
1456
+ - "Liganame ist erforderlich" - League name is required
1457
+ - "Staffelname ist erforderlich" - League group name is required
1458
+ - "Hallenname ist erforderlich" - Gym name is required
1459
+ - "Teamname ist erforderlich" - Team name is required
1460
+ - "Vorname ist erforderlich" - First name is required
1461
+ - "Nachname ist erforderlich" - Last name is required
1462
+ - "Saison-Enddatum muss nach dem Startdatum liegen" - Season end date must be after start date
1463
+ - "Anmeldungsende muss nach dem Anmeldungsstart liegen" - Registration end must be after registration start
852
1464
  - "Ungültiges E-Mail-Format" - Invalid email format
853
- - "Mindestens 2 Spieler erforderlich" - At least 2 players required
854
- - "Verein ist erforderlich" - Club is required
855
- - "Saison ist erforderlich" - Season is required
1465
+ - "Es müssen mindestens 2 Spieler für ein Team angegeben werden" - At least 2 players must be specified for a team
1466
+ - "Maximalalter muss größer oder gleich dem Mindestalter sein" - Max age must be greater than or equal to min age
1467
+ - "Stadt ist erforderlich" - City is required
1468
+ - "Land ist erforderlich" - Country is required
1469
+ - "Straße ist erforderlich" - Street is required
1470
+ - "PLZ ist erforderlich" - Postal code is required