Files
harheimertc/server/api/mitgliederbereich/qttr.get.js
Torsten Schulz (local) 1a7ba583d8
Some checks failed
Code Analysis and Production Deploy / analyze (push) Failing after 5m18s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Has been skipped
Aktualisiere die Version auf 1.8.10 und füge Vereinsrang (QTTR / TTR) zur QTTR-Tabelle hinzu. Implementiere die Logik zur Berechnung und Sortierung der Vereinsränge in den API- und Import-Skripten.
2026-09-23 16:00:06 +02:00

122 lines
4.1 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFile } from 'fs/promises'
import { getServerDataPath } from '../../utils/paths.js'
import { getUserFromToken, verifyToken, readUsers, isHiddenUser, normalizeUserEmail } from '../../utils/auth.js'
import { readMembers } from '../../utils/members.js'
const QTTR_FILE = getServerDataPath('qttr-values.json')
function normalizeName(value) {
return String(value || '')
.trim()
.toLowerCase()
.normalize('NFKD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/\s+/g, ' ')
.replace(/['`]/g, '')
}
function buildBirthdateLookup(entries) {
const lookup = new Map()
for (const entry of entries || []) {
const candidates = [
entry?.name,
`${entry?.firstName || ''} ${entry?.lastName || ''}`.trim(),
]
const birthdate = entry?.geburtsdatum || entry?.birthday || entry?.birthDate || ''
if (!birthdate) continue
for (const candidate of candidates) {
const normalized = normalizeName(candidate)
if (!normalized || lookup.has(normalized)) continue
lookup.set(normalized, birthdate)
}
}
return lookup
}
function addClubRanks(rows) {
const addRankFor = (valueKey, rankKey) => {
rows
.filter((row) => row[valueKey] != null)
.sort((a, b) => b[valueKey] - a[valueKey] || String(a.playerName || '').localeCompare(String(b.playerName || ''), 'de'))
.forEach((row, index) => {
row[rankKey] = index + 1
})
}
addRankFor('currentQttr', 'clubQttrRank')
addRankFor('currentTtr', 'clubTtrRank')
return rows.sort((a, b) =>
(a.clubQttrRank ?? Number.POSITIVE_INFINITY) - (b.clubQttrRank ?? Number.POSITIVE_INFINITY)
|| (a.clubTtrRank ?? Number.POSITIVE_INFINITY) - (b.clubTtrRank ?? Number.POSITIVE_INFINITY)
|| String(a.playerName || '').localeCompare(String(b.playerName || ''), 'de')
)
}
export default defineEventHandler(async (event) => {
const token = getCookie(event, 'auth_token') || getHeader(event, 'authorization')?.replace(/^Bearer\s+/i, '')
if (!token || !verifyToken(token)) {
throw createError({
statusCode: 401,
message: 'Nicht authentifiziert.'
})
}
const currentUser = await getUserFromToken(token)
if (!currentUser) {
throw createError({
statusCode: 401,
message: 'Ungültiges Token.'
})
}
try {
const content = await readFile(QTTR_FILE, 'utf8')
const payload = JSON.parse(content)
const [manualMembers, registeredUsers] = await Promise.all([
readMembers(),
readUsers()
])
const hiddenUserEmails = new Set(registeredUsers.filter(isHiddenUser).map(user => normalizeUserEmail(user.email)).filter(Boolean))
const visibleManualMembers = manualMembers.filter(member => {
const email = normalizeUserEmail(member.email)
return member.hidden !== true && member.invisible !== true && member.isHidden !== true && !hiddenUserEmails.has(email)
})
const visibleUsers = registeredUsers.filter(user => !isHiddenUser(user))
const hiddenNames = new Set([
...manualMembers.filter(member => member.hidden === true || member.invisible === true || member.isHidden === true || hiddenUserEmails.has(normalizeUserEmail(member.email))),
...registeredUsers.filter(isHiddenUser)
].flatMap(entry => [entry?.name, `${entry?.firstName || ''} ${entry?.lastName || ''}`.trim()]).map(normalizeName).filter(Boolean))
const birthdateLookup = buildBirthdateLookup([...visibleManualMembers, ...visibleUsers])
const rankedRows = addClubRanks(Array.isArray(payload.rows) ? payload.rows.map(row => ({ ...row })) : [])
return {
...payload,
rows: rankedRows
.filter(row => !hiddenNames.has(normalizeName(row.playerName)))
.map((row) => ({
...row,
birthdate: birthdateLookup.get(normalizeName(row.playerName)) || row.birthdate || ''
}))
}
} catch (error) {
if (error?.code === 'ENOENT') {
throw createError({
statusCode: 404,
message: 'QTTR-Datei nicht gefunden.'
})
}
console.error('Fehler beim Laden der QTTR-Werte:', error)
throw createError({
statusCode: 500,
message: 'Fehler beim Laden der QTTR-Werte.'
})
}
})