diff --git a/server/utils/mytischtennis-client.js b/server/utils/mytischtennis-client.js index 0074b2d..efbf9c5 100644 --- a/server/utils/mytischtennis-client.js +++ b/server/utils/mytischtennis-client.js @@ -148,17 +148,23 @@ async function loginWithBrowser(email, password) { } finally { await browser.close() } } -export async function fetchClubRankings(connection) { +export async function fetchClubRankings(connection, currentRanking = 'yes') { let cookie try { cookie = await loginDirect(connection.email, connection.password) } catch (error) { if (error.message !== 'CAPTCHA_REQUIRED') throw error cookie = await loginWithBrowser(connection.email, connection.password) } const url = new URL('/rankings/andro-rangliste', BASE_URL) - url.search = new URLSearchParams({ 'all-players': 'on', clubnr: connection.clubId, fednickname: connection.association, 'current-ranking': 'yes', 'results-per-page': '100', page: '0', _data: 'routes/$' }) + url.search = new URLSearchParams({ 'all-players': 'on', clubnr: connection.clubId, fednickname: connection.association, 'current-ranking': currentRanking, 'results-per-page': '100', page: '0', _data: 'routes/$' }) + console.info('[mytischtennis] Ranking request URL:', url.toString()) const response = await fetch(url, { headers: { ...HEADERS, cookie, accept: 'application/json', referer: `${BASE_URL}/` } }) if (!response.ok) throw new Error(`Ranglisten-Abruf fehlgeschlagen (HTTP ${response.status}).`) const entries = findEntries(await response.json()) if (!entries) throw new Error('myTischtennis hat keine Ranglisten-Daten geliefert.') + console.info('[mytischtennis] Ranking response:', { + currentRanking, + entryCount: entries.length, + entryKeys: Object.keys(entries[0] || {}) + }) return entries } diff --git a/server/utils/qttr-import.js b/server/utils/qttr-import.js index a565edd..7eb35e6 100755 --- a/server/utils/qttr-import.js +++ b/server/utils/qttr-import.js @@ -215,19 +215,29 @@ export async function importQttrValues(options = {}) { } async function importAuthenticatedTtrValues(connection) { - const entries = await fetchClubRankings(connection) - const rows = entries.map((entry, index) => ({ + const [ttrEntries, qttrEntries] = await Promise.all([ + fetchClubRankings(connection, 'yes'), + fetchClubRankings(connection, 'no') + ]) + const qttrByPlayer = new Map(qttrEntries.map(entry => [ + String(entry.personId || `${entry.firstname || ''}|${entry.lastname || ''}`).toLowerCase(), entry + ])) + const rows = ttrEntries.map((entry, index) => { + const key = String(entry.personId || `${entry.firstname || ''}|${entry.lastname || ''}`).toLowerCase() + const qttrEntry = qttrByPlayer.get(key) + return ({ rank: toNumberOrNull(entry.rank ?? entry.ranking ?? index + 1), playerNumber: toNumberOrNull(entry.playernr ?? entry.player_number ?? entry.nuid), gender: normalizeGender(entry.gender), playerName: `${entry.firstname ?? entry.first_name ?? ''} ${entry.lastname ?? entry.last_name ?? ''}`.trim() || entry.name || null, clubName: entry.clubname ?? entry.club_name ?? 'Harheimer TC', - currentQttr: toNumberOrNull(entry.qttr ?? entry.q_ttr ?? entry.ttr), - currentTtr: toNumberOrNull(entry.ttr ?? entry.current_ttr), + currentQttr: toNumberOrNull(qttrEntry?.fedRank ?? qttrEntry?.qttr ?? entry.qttr), + currentTtr: toNumberOrNull(entry.fedRank ?? entry.ttr ?? entry.current_ttr), previousQttr: null, valuesByHeader: entry, rawCells: [] - })).filter(row => row.playerName && row.currentQttr != null) + }) + }).filter(row => row.playerName && (row.currentTtr != null || row.currentQttr != null)) if (!rows.length) throw new Error('Keine verwertbaren TTR-Werte in der myTischtennis-Rangliste gefunden.') const importedAt = new Date().toISOString()