Füge myTischtennis-Verbindung hinzu: Implementiere Authentifizierung, Import von TTR-Werten und speichere Verbindungsdaten sicher
Some checks failed
Code Analysis and Production Deploy / analyze (push) Failing after 8m54s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Has been skipped

This commit is contained in:
Torsten Schulz (local)
2026-09-04 12:45:22 +02:00
parent 3314aa06b4
commit 8f6fda2e61
10 changed files with 301 additions and 4 deletions

View File

@@ -1,5 +1,7 @@
import { promises as fs } from 'fs'
import { getServerDataPath } from './paths.js'
import { fetchClubRankings } from './mytischtennis-client.js'
import { readMyTischtennisConnection, saveMyTischtennisConnection } from './mytischtennis-connection.js'
const QTTR_URL = 'https://www.mytischtennis.de/rankings/andro-rangliste?continent=all&country=Deutschland&all-players=on&as=DE.WE.R4.07&di=DE.WE.R4.07.04&area=DE.WE.R4.07.04.43&clubnr-search=Harheimer+TC&clubnr=43030&fednickname=HeTTV&gender=all&current-ranking=no&ttr-range=100%3B3000&birth-range=1926%3B2021'
const OUTPUT_FILE = getServerDataPath('qttr-values.json')
@@ -160,6 +162,9 @@ function deriveQttrFields(headers, cells) {
}
export async function importQttrValues(options = {}) {
const connection = options.connection ?? await readMyTischtennisConnection()
if (connection) return importAuthenticatedTtrValues(connection)
const url = options.url || QTTR_URL
const response = await fetch(url, {
headers: {
@@ -207,4 +212,32 @@ export async function importQttrValues(options = {}) {
rowCount: parsedRows.length,
...payload
}
}
}
async function importAuthenticatedTtrValues(connection) {
const entries = await fetchClubRankings(connection)
const rows = entries.map((entry, index) => ({
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),
previousQttr: null,
valuesByHeader: entry,
rawCells: []
})).filter(row => row.playerName && row.currentQttr != null)
if (!rows.length) throw new Error('Keine verwertbaren TTR-Werte in der myTischtennis-Rangliste gefunden.')
const importedAt = new Date().toISOString()
const payload = {
format: 'harheimertc.qttr.v2', importedAt,
source: { type: 'mytischtennis-authenticated', association: connection.association, clubId: connection.clubId },
title: 'Aktuelle myTischtennis-Rangliste', headerCount: 0, rowCount: rows.length, headers: [], rows
}
await fs.mkdir(getServerDataPath(), { recursive: true })
await fs.writeFile(OUTPUT_FILE, `${JSON.stringify(payload, null, 2)}\n`, 'utf8')
await saveMyTischtennisConnection({ ...connection, lastSuccessfulImportAt: importedAt, lastImportError: null })
return { outputFile: OUTPUT_FILE, tableCount: 1, ...payload }
}