Add validation for maxTeams amount and refresh Team count properly

This commit is contained in:
2026-03-13 19:04:07 +01:00
parent 82f5da58f8
commit 9817f7080e
4 changed files with 60 additions and 18 deletions

View File

@@ -199,6 +199,12 @@ app.post('/tournaments/:id/teams', authMiddleware, async (req: Request, res: Res
const entry = await teamService.registerTeamForTournament(+req.params.id, +teamId);
res.status(201).send(entry);
} catch (err: any) {
if (err.message === 'Turnier nicht gefunden') {
return res.status(404).send({error: err.message});
}
if (err.message === 'Das Turnier hat bereits die maximale Anzahl an Teams erreicht') {
return res.status(409).send({error: err.message});
}
if (err.message?.includes('UNIQUE constraint failed')) {
return res.status(409).send({error: 'Das Team ist bereits für dieses Turnier angemeldet'});
}

View File

@@ -145,19 +145,38 @@ export class TeamService {
registerTeamForTournament(tournamentId: number, teamId: number): Promise<TournamentTeam> {
return new Promise<TournamentTeam>((resolve, reject) => {
const stmt = this.db.prepare(
`INSERT INTO TournamentTeams (tournamentId, teamId) VALUES (?, ?)`
this.db.get(
`SELECT t.maxTeamAmount as maxTeamAmount,
COUNT(tt.id) as currentTeamAmount
FROM Tournaments t
LEFT JOIN TournamentTeams tt ON t.id = tt.tournamentId
WHERE t.id = ?
GROUP BY t.id`,
[tournamentId],
(err: Error | null, row: any) => {
if (err) return reject(err);
if (!row) {
return reject(new Error('Turnier nicht gefunden'));
}
if (row.currentTeamAmount >= row.maxTeamAmount) {
return reject(new Error('Das Turnier hat bereits die maximale Anzahl an Teams erreicht'));
}
const stmt = this.db.prepare(
`INSERT INTO TournamentTeams (tournamentId, teamId) VALUES (?, ?)`
);
stmt.run(tournamentId, teamId, function (this: RunResult, err: Error | null) {
if (err) return reject(err);
resolve({
id: (this as any).lastID,
tournamentId,
teamId,
registeredAt: new Date().toISOString(),
});
});
stmt.finalize();
}
);
stmt.run(tournamentId, teamId, function (this: RunResult, err: Error | null) {
if (err) return reject(err);
resolve({
id: (this as any).lastID,
tournamentId,
teamId,
registeredAt: new Date().toISOString(),
});
});
stmt.finalize();
});
}

View File

@@ -192,3 +192,9 @@ Folgende Dateien wurden in diesem Prompt verändert:
Folgende Dateien wurden in diesem Prompt verändert:
- backend_splatournament_manager/src/services/match-service.ts
- frontend_splatournament_manager/lib/pages/tournament_bracket_page.dart
- Add a validation that you can only enter a tournament with at most maxTeams teams.
Folgende Dateien wurden in diesem Prompt verändert:
- backend_splatournament_manager/src/services/team-service.ts
- backend_splatournament_manager/src/app.ts
- docs/prompts.md

View File

@@ -3,6 +3,7 @@ import 'package:frontend_splatournament_manager/models/team.dart';
import 'package:frontend_splatournament_manager/models/tournament.dart';
import 'package:frontend_splatournament_manager/pages/tournament_bracket_page.dart';
import 'package:frontend_splatournament_manager/providers/team_provider.dart';
import 'package:frontend_splatournament_manager/providers/tournament_provider.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
@@ -84,7 +85,12 @@ class _TournamentDetailPageState extends State<TournamentDetailPage> {
);
if (!context.mounted) return;
await Provider.of<TournamentProvider>(
context,
listen: false,
).refreshAvailableTournaments();
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
@@ -413,11 +419,16 @@ class DetailHeader extends StatelessWidget {
Spacer(),
Row(
children: [
InputChip(
onPressed: () => onTeamsChipClicked(),
label: Text(
'${tournament.currentTeamAmount} von ${tournament.maxTeamAmount} Teams',
),
Consumer<TournamentProvider>(
builder: (context, value, child){
final currentTournament = value.availableTournaments.firstWhere((t) => t.id == tournament.id);
return InputChip(
onPressed: () => onTeamsChipClicked(),
label: Text(
'${currentTournament.currentTeamAmount} von ${currentTournament.maxTeamAmount} Teams',
),
);
}
),
],
),