diff --git a/backend/server.js b/backend/server.js index 9916c17..99b12bc 100644 --- a/backend/server.js +++ b/backend/server.js @@ -71,6 +71,31 @@ process.on('unhandledRejection', (reason, promise) => { console.error('[unhandledRejection]', reason); }); +// Globale Fehlerbehandlung für API-Routen +app.use((err, req, res, next) => { + if (res.headersSent) { + return next(err); + } + + const status = err?.statusCode || err?.status || 500; + const message = err?.message || 'Interner Serverfehler'; + + const response = { + success: false, + message, + error: message + }; + + if (process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development') { + response.debug = { + stack: err?.stack || null + }; + } + + console.error('[ExpressError]', err); + res.status(status).json(response); +}); + app.use('/api/auth', authRoutes); app.use('/api/clubs', clubRoutes); app.use('/api/clubmembers', memberRoutes); diff --git a/backend/services/autoUpdateRatingsService.js b/backend/services/autoUpdateRatingsService.js index 2f58884..80fbb6f 100644 --- a/backend/services/autoUpdateRatingsService.js +++ b/backend/services/autoUpdateRatingsService.js @@ -4,6 +4,7 @@ import memberService from './memberService.js'; import myTischtennisClient from '../clients/myTischtennisClient.js'; import MyTischtennis from '../models/MyTischtennis.js'; import { devLog } from '../utils/logger.js'; +import UserClub from '../models/UserClub.js'; class AutoUpdateRatingsService { /** @@ -134,8 +135,27 @@ class AutoUpdateRatingsService { devLog(`Updating ratings for ${account.email}`); try { - // Use the memberService to update ratings from MyTischtennis - const result = await memberService.updateRatingsFromMyTischtennis(account.userId); + // Ermittle einen freigeschalteten Vereinszugang für den Benutzer + const userClub = await UserClub.findOne({ + where: { + userId: account.userId, + approved: true + }, + order: [['createdAt', 'ASC']], + attributes: ['clubId'] + }); + + if (!userClub) { + throw new Error('Kein freigeschalteter Vereinszugang gefunden'); + } + + const clubId = userClub.clubId; + + // Verwende den Service-Aufruf, der mit userId/clubId arbeitet + const result = await memberService.updateRatingsFromMyTischtennisByUserId( + account.userId, + clubId + ); return { success: true, diff --git a/frontend/src/views/MyTischtennisAccount.vue b/frontend/src/views/MyTischtennisAccount.vue index bcce970..5780ad3 100644 --- a/frontend/src/views/MyTischtennisAccount.vue +++ b/frontend/src/views/MyTischtennisAccount.vue @@ -287,7 +287,7 @@ export default { }); await this.loadAccount(); // Aktualisiere Account-Daten inkl. clubId, fedNickname } catch (error) { - const message = error.response?.data?.message || 'Login fehlgeschlagen'; + const message = error.response?.data?.message || error.response?.data?.error || error.message || 'Login fehlgeschlagen'; if (error.response?.status === 400 && message.includes('Kein Passwort gespeichert')) { // Passwort-Dialog öffnen