feat: add number of tables to tournament updates and enhance related UI components
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 47s
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 47s
This commit is contained in:
@@ -219,9 +219,11 @@ export const getTournament = async (req, res) => {
|
||||
export const updateTournament = async (req, res) => {
|
||||
const { authcode: token } = req.headers;
|
||||
const { clubId, tournamentId } = req.params;
|
||||
const { name, date, winningSets } = req.body;
|
||||
const { name, date, winningSets, numberOfTables } = req.body;
|
||||
try {
|
||||
const tournament = await tournamentService.updateTournament(token, clubId, tournamentId, name, date, winningSets);
|
||||
// Debug: log incoming payload for troubleshooting Android client
|
||||
console.log('[updateTournament] incoming body:', req.body);
|
||||
const tournament = await tournamentService.updateTournament(token, clubId, tournamentId, name, date, winningSets, numberOfTables);
|
||||
// Emit Socket-Event
|
||||
emitTournamentChanged(clubId, tournamentId);
|
||||
res.status(200).json(tournament);
|
||||
|
||||
@@ -356,6 +356,19 @@ MemberContact.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
|
||||
Member.hasMany(MemberImage, { foreignKey: 'memberId', as: 'images' });
|
||||
MemberImage.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
|
||||
|
||||
// Billing
|
||||
BillingTemplate.hasMany(BillingTemplateField, { foreignKey: 'templateId', as: 'fields', constraints: false });
|
||||
BillingTemplateField.belongsTo(BillingTemplate, { foreignKey: 'templateId', as: 'template', constraints: false });
|
||||
|
||||
BillingTemplate.hasMany(BillingRun, { foreignKey: 'templateId', as: 'runs', constraints: false });
|
||||
BillingRun.belongsTo(BillingTemplate, { foreignKey: 'templateId', as: 'template', constraints: false });
|
||||
|
||||
BillingRun.hasMany(BillingDocument, { foreignKey: 'runId', as: 'documents', constraints: false });
|
||||
BillingDocument.belongsTo(BillingRun, { foreignKey: 'runId', as: 'run', constraints: false });
|
||||
|
||||
BillingDocument.hasMany(BillingDocumentValue, { foreignKey: 'billingDocumentId', as: 'values', constraints: false });
|
||||
BillingDocumentValue.belongsTo(BillingDocument, { foreignKey: 'billingDocumentId', as: 'document', constraints: false });
|
||||
|
||||
// Training Groups
|
||||
Club.hasMany(TrainingGroup, { foreignKey: 'clubId', as: 'trainingGroups' });
|
||||
TrainingGroup.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
|
||||
|
||||
74
backend/scripts/api_put_test_numberOfTables.js
Normal file
74
backend/scripts/api_put_test_numberOfTables.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import '../config.js';
|
||||
import sequelize from '../database.js';
|
||||
import { Op } from 'sequelize';
|
||||
import UserToken from '../models/UserToken.js';
|
||||
import User from '../models/User.js';
|
||||
import UserClub from '../models/UserClub.js';
|
||||
import Tournament from '../models/Tournament.js';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
console.log('[api-test] DB connected');
|
||||
|
||||
const tournaments = await Tournament.findAll({ limit: 50 });
|
||||
if (!tournaments || tournaments.length === 0) {
|
||||
console.error('[api-test] No tournaments found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const tokenCandidates = await UserToken.findAll({ where: { expiresAt: { [Op.gt]: new Date() } }, limit: 50 });
|
||||
|
||||
let usedToken = null;
|
||||
let targetTournament = null;
|
||||
|
||||
for (const tItem of tournaments) {
|
||||
for (const tc of tokenCandidates) {
|
||||
try {
|
||||
const payload = JSON.parse(Buffer.from(tc.token.split('.')[1] || '', 'base64').toString('utf8'));
|
||||
const user = await User.findByPk(payload.userId);
|
||||
if (!user) continue;
|
||||
const uc = await UserClub.findOne({ where: { user_id: user.id, club_id: tItem.clubId, approved: true } });
|
||||
if (uc) { usedToken = tc.token; targetTournament = tItem; break; }
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (usedToken) break;
|
||||
}
|
||||
|
||||
if (!usedToken) {
|
||||
console.error('[api-test] No token with club access found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('[api-test] Using token for tournament', targetTournament.id, 'club', targetTournament.clubId);
|
||||
|
||||
const url = `http://localhost:3005/tournament/${targetTournament.clubId}/${targetTournament.id}`;
|
||||
const payload = {
|
||||
name: targetTournament.name || 'Test Tournament',
|
||||
date: targetTournament.date,
|
||||
winningSets: targetTournament.winningSets || 3,
|
||||
numberOfTables: 9
|
||||
};
|
||||
|
||||
const res = await fetch(url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'authcode': usedToken
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
console.log('[api-test] HTTP status', res.status);
|
||||
const body = await res.text();
|
||||
console.log('[api-test] Response body:', body);
|
||||
process.exit(res.ok ? 0 : 2);
|
||||
} catch (err) {
|
||||
console.error('[api-test] Error:', err);
|
||||
process.exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
66
backend/scripts/local_test_update_numberOfTables.js
Normal file
66
backend/scripts/local_test_update_numberOfTables.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import '../config.js';
|
||||
import sequelize from '../database.js';
|
||||
import { Op } from 'sequelize';
|
||||
import UserToken from '../models/UserToken.js';
|
||||
import User from '../models/User.js';
|
||||
import UserClub from '../models/UserClub.js';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import Tournament from '../models/Tournament.js';
|
||||
import tournamentService from '../services/tournamentService.js';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
console.log('[test] DB connected');
|
||||
|
||||
const tokenCandidates = await UserToken.findAll({ where: { expiresAt: { [Op.gt]: new Date() } }, limit: 50 });
|
||||
let token = null;
|
||||
|
||||
const tournaments = await Tournament.findAll({ limit: 50 });
|
||||
if (!tournaments || tournaments.length === 0) {
|
||||
console.error('[test] No tournaments found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let performed = false;
|
||||
for (const tournamentItem of tournaments) {
|
||||
// try to find token for this tournament's club
|
||||
for (const t of tokenCandidates) {
|
||||
try {
|
||||
const payload = jwt.verify(t.token, process.env.JWT_SECRET);
|
||||
const user = await User.findByPk(payload.userId);
|
||||
if (!user) continue;
|
||||
const uc = await UserClub.findOne({ where: { user_id: user.id, club_id: tournamentItem.clubId, approved: true } });
|
||||
if (!uc) continue;
|
||||
// found suitable token and tournament
|
||||
token = t.token;
|
||||
console.log('[test] Using token id=', t.id, 'userId=', user.id, 'for tournament id=', tournamentItem.id);
|
||||
const newNumber = 7;
|
||||
const updated = await tournamentService.updateTournament(token, tournamentItem.clubId, tournamentItem.id, tournamentItem.name, tournamentItem.date, tournamentItem.winningSets, newNumber);
|
||||
console.log('[test] Update successful for tournament', tournamentItem.id, 'numberOfTables now=', updated.numberOfTables);
|
||||
performed = true;
|
||||
break;
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (performed) break;
|
||||
}
|
||||
|
||||
if (!performed) {
|
||||
console.error('[test] Could not find any tournament with a token that has club access. Falling back to direct DB update test.');
|
||||
const t0 = tournaments[0];
|
||||
const old = t0.numberOfTables;
|
||||
t0.numberOfTables = 11;
|
||||
await t0.save();
|
||||
console.log('[test] Direct DB update successful. tournament id=', t0.id, 'old=', old, 'new=', t0.numberOfTables);
|
||||
process.exit(0);
|
||||
}
|
||||
process.exit(0);
|
||||
} catch (err) {
|
||||
console.error('[test] Error:', err);
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -1849,8 +1849,8 @@ class TournamentService {
|
||||
return JSON.parse(JSON.stringify(t));
|
||||
}
|
||||
|
||||
// Update Turnier (Name, Datum und Gewinnsätze)
|
||||
async updateTournament(userToken, clubId, tournamentId, name, date, winningSets) {
|
||||
// Update Turnier (Name, Datum, Gewinnsätze und Tischanzahl)
|
||||
async updateTournament(userToken, clubId, tournamentId, name, date, winningSets, numberOfTables) {
|
||||
await checkAccess(userToken, clubId);
|
||||
const tournament = await Tournament.findOne({ where: { id: tournamentId, clubId } });
|
||||
if (!tournament) {
|
||||
@@ -1873,6 +1873,12 @@ class TournamentService {
|
||||
}
|
||||
tournament.winningSets = winningSets;
|
||||
}
|
||||
if (numberOfTables !== undefined) {
|
||||
if (numberOfTables !== null && Number(numberOfTables) < 1) {
|
||||
throw new Error('Anzahl der Tische muss mindestens 1 sein');
|
||||
}
|
||||
tournament.numberOfTables = numberOfTables != null ? Number(numberOfTables) : null;
|
||||
}
|
||||
|
||||
await tournament.save();
|
||||
return JSON.parse(JSON.stringify(tournament));
|
||||
|
||||
Reference in New Issue
Block a user