@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.
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/enums/RegistrationPermission.html +4 -0
- package/docs/modules.html +1 -1
- package/docs/types/Association.html +3 -2
- package/docs/types/Competition.html +18 -0
- package/docs/types/CompetitionGroup.html +11 -0
- package/docs/types/CompetitionGroupStatistics.html +6 -0
- package/docs/types/CompetitionGroupView.html +7 -0
- package/docs/types/CompetitionRegistrationError.html +6 -0
- package/docs/types/CompetitionRegistrationResult.html +5 -0
- package/docs/types/CompetitionTeam.html +12 -0
- package/docs/types/ModifyCompetitionGroupInput.html +7 -0
- package/docs/types/ModifyCompetitionInput.html +15 -0
- package/docs/types/ModifyCompetitionTeamInput.html +9 -0
- package/docs/types/Mutation.html +13 -2
- package/docs/types/MutationAddCompetitionArgs.html +2 -0
- package/docs/types/MutationAddCompetitionGroupArgs.html +2 -0
- package/docs/types/MutationAddCompetitionTeamArgs.html +2 -0
- package/docs/types/MutationModifyCompetitionArgs.html +2 -0
- package/docs/types/MutationModifyCompetitionGroupArgs.html +2 -0
- package/docs/types/MutationModifyCompetitionTeamArgs.html +2 -0
- package/docs/types/MutationRegisterCompetitionTeamsArgs.html +2 -0
- package/docs/types/MutationRemoveCompetitionArgs.html +2 -0
- package/docs/types/MutationRemoveCompetitionGroupArgs.html +2 -0
- package/docs/types/MutationRemoveCompetitionTeamArgs.html +2 -0
- package/docs/types/MutationUpdateCompetitionTeamGroupArgs.html +3 -0
- package/docs/types/Query.html +11 -2
- package/docs/types/QueryCanClubRegisterForCompetitionArgs.html +3 -0
- package/docs/types/QueryGetCompetitionByIdArgs.html +2 -0
- package/docs/types/QueryGetCompetitionGroupByIdArgs.html +2 -0
- package/docs/types/QueryGetCompetitionGroupViewArgs.html +2 -0
- package/docs/types/QueryGetCompetitionTeamByIdArgs.html +2 -0
- package/docs/types/QueryGetListOfCompetitionsArgs.html +2 -0
- package/docs/types/QueryGetListOfGroupsInCompetitionArgs.html +2 -0
- package/docs/types/QueryGetListOfTeamsInCompetitionArgs.html +2 -0
- package/docs/types/QueryGetListOfTeamsInCompetitionGroupArgs.html +2 -0
- package/docs/types/RegisterCompetitionTeamInput.html +9 -0
- package/docs/types/RegisterCompetitionTeamsInput.html +5 -0
- package/docs/types/RegistrationEligibility.html +6 -0
- package/docs/types/SaveCompetitionGroupInput.html +7 -0
- package/docs/types/SaveCompetitionInput.html +15 -0
- package/docs/types/SaveCompetitionTeamInput.html +10 -0
- package/lib/generated/graphql.model.generated.d.ts +252 -0
- package/lib/generated/graphql.model.generated.js +8 -2
- package/llm.md +1055 -440
- package/package.json +1 -1
- 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
|
-
|
|
111
|
+
validateGym,
|
|
112
|
+
validateLeague,
|
|
113
|
+
validateLeagueGroup,
|
|
43
114
|
validatePerson,
|
|
115
|
+
validateSeason,
|
|
116
|
+
validateTeam,
|
|
117
|
+
checkAddress,
|
|
44
118
|
checkAssociation,
|
|
45
119
|
checkClub,
|
|
46
|
-
|
|
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
|
-
|
|
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
|
|
78
|
-
type Maybe<T> = T |
|
|
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 |
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
189
|
+
// Create input
|
|
101
190
|
interface SaveAssociationInput {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
|
257
|
+
// Create input
|
|
141
258
|
interface SaveClubInput {
|
|
142
|
-
associationId: Scalars['ID'];
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
207
|
-
|
|
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
|
|
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
|
-
|
|
248
|
-
|
|
321
|
+
clubId: 'club-123',
|
|
322
|
+
firstName: 'Max',
|
|
323
|
+
lastName: 'Mustermann',
|
|
249
324
|
email: 'max@example.com',
|
|
250
|
-
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Create
|
|
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
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
406
|
+
registrationStart: '2024-07-01',
|
|
407
|
+
registrationEnd: '2024-08-15',
|
|
408
|
+
additionalEligibleAssociations: []
|
|
304
409
|
};
|
|
305
410
|
```
|
|
306
411
|
|
|
307
|
-
### League
|
|
412
|
+
### League
|
|
308
413
|
|
|
309
414
|
```typescript
|
|
310
|
-
//
|
|
415
|
+
// Type definition
|
|
311
416
|
interface League {
|
|
312
417
|
__typename?: 'League';
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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
|
|
430
|
+
// Create input
|
|
340
431
|
interface SaveLeagueInput {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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 {
|
|
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.
|
|
971
|
+
if (Object.keys(result.errors).length > 0) {
|
|
405
972
|
console.error('Validation errors:', result.errors);
|
|
406
|
-
// Output: { name: ['
|
|
973
|
+
// Output: { name: ['Vereinsname ist erforderlich'] }
|
|
407
974
|
}
|
|
408
975
|
|
|
409
976
|
// Check with warnings
|
|
410
977
|
const personData: SavePersonInput = {
|
|
411
|
-
|
|
412
|
-
|
|
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.
|
|
985
|
+
if (Object.keys(personResult.errors).length > 0) {
|
|
418
986
|
console.log('Errors:', personResult.errors);
|
|
419
|
-
console.log('
|
|
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
|
-
|
|
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
|
-
|
|
451
|
-
|
|
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
|
-
###
|
|
1049
|
+
### Season Registration Check
|
|
463
1050
|
|
|
464
1051
|
```typescript
|
|
465
|
-
import {
|
|
1052
|
+
import { isSeasonOpenForRegistration } from '@taimos/radball-digital-api';
|
|
466
1053
|
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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 {
|
|
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:
|
|
522
|
-
associationId: 'assoc-123',
|
|
1111
|
+
const listClubsArgs: QueryGetListOfClubsArgs = {
|
|
523
1112
|
limit: 20,
|
|
524
1113
|
nextToken: undefined // For pagination
|
|
525
1114
|
};
|
|
526
1115
|
|
|
527
|
-
//
|
|
528
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
542
|
-
|
|
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
|
-
|
|
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
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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
|
-
|
|
563
|
-
|
|
564
|
-
|
|
1163
|
+
leagueId: 'league-789',
|
|
1164
|
+
name: 'RV Musterhausen I',
|
|
1165
|
+
playerIds: ['person-1', 'person-2']
|
|
1166
|
+
}
|
|
1167
|
+
],
|
|
1168
|
+
preferredDates: [
|
|
565
1169
|
{
|
|
566
|
-
|
|
567
|
-
|
|
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:
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
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
|
-
//
|
|
599
|
-
const
|
|
600
|
-
|
|
601
|
-
|
|
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
|
-
//
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
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.
|
|
620
|
-
const last = person.
|
|
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
|
|
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.
|
|
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.
|
|
1267
|
+
return season.registrationStart <= today && today <= season.registrationEnd;
|
|
655
1268
|
}
|
|
656
1269
|
|
|
657
|
-
//
|
|
658
|
-
function
|
|
659
|
-
|
|
660
|
-
|
|
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
|
|
1297
|
+
if (error.message) {
|
|
688
1298
|
// Parse validation errors
|
|
689
|
-
|
|
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
|
|
775
|
-
console.log(`Total Players: ${stats
|
|
776
|
-
console.log(`Total Clubs: ${stats
|
|
777
|
-
console.log(`Total Gyms: ${stats
|
|
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<{
|
|
788
|
-
): Promise<
|
|
1389
|
+
registrations: Array<{ leagueId: string; name: string; playerIds: string[] }>
|
|
1390
|
+
): Promise<Team[]> {
|
|
789
1391
|
// Validate all registrations first
|
|
790
|
-
const
|
|
791
|
-
const result =
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
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
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
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
|
|
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. **
|
|
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
|
|
837
|
-
- **Short names**:
|
|
838
|
-
- **Emails**: Must
|
|
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
|
|
842
|
-
- **Age restrictions**:
|
|
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
|
-
- **
|
|
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
|
-
- "
|
|
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
|
-
- "
|
|
854
|
-
- "
|
|
855
|
-
- "
|
|
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
|