Füge Unterstützung für TTR-Änderungen hinzu: Erweitere Benachrichtigungseinstellungen und implementiere Push-Benachrichtigungen für TTR-Wertänderungen.
Some checks failed
Code Analysis and Production Deploy / deploy-production (push) Has been cancelled
Code Analysis and Production Deploy / deploy-test (push) Has been cancelled
Code Analysis and Production Deploy / analyze (push) Has been cancelled

This commit is contained in:
Torsten Schulz (local)
2026-09-08 14:54:20 +02:00
parent 5ca4253b44
commit 9bc9501219
12 changed files with 117 additions and 22 deletions

View File

@@ -150,6 +150,26 @@ function isVorstandUser(user) {
return roles.includes('admin') || roles.includes('vorstand')
}
function normalizePersonName(value) {
return String(value || '')
.trim()
.toLowerCase()
.normalize('NFKD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/['`]/g, '')
.replace(/\s+/g, ' ')
}
function userMatchesPlayer(user, playerName) {
const player = normalizePersonName(playerName)
if (!player) return false
const candidates = [
user?.name,
`${user?.firstName || ''} ${user?.lastName || ''}`.trim()
].map(normalizePersonName).filter(Boolean)
return candidates.includes(player)
}
export async function sendPushToUsers({ title, body, data = {}, predicate, bodyForUser, dataForUser, failureLabel = 'FCM-Push' }) {
const serviceAccount = await readServiceAccount()
if (serviceAccount == null) {
@@ -275,3 +295,44 @@ export async function sendNewUserRegistrationPush(registration) {
failureLabel: 'FCM Registrierungs-Push'
})
}
export async function sendOwnTtrChangePush(changes = []) {
const byPlayer = new Map(
changes
.filter(change => change?.playerName && Number.isFinite(change?.previousTtr) && Number.isFinite(change?.currentTtr))
.map(change => [normalizePersonName(change.playerName), change])
)
if (!byPlayer.size) return { sent: 0, failed: 0, removed: 0, recipients: 0, tokenCount: 0, skipped: false }
return sendPushToUsers({
title: 'TTR-Wert geändert',
data: { type: 'ttr_change' },
predicate: (user, settings) => settings.ownTtrChanges && [...byPlayer.values()].some(change => userMatchesPlayer(user, change.playerName)),
bodyForUser: (user) => {
const change = [...byPlayer.values()].find(entry => userMatchesPlayer(user, entry.playerName))
return `Dein TTR-Wert hat sich von ${change.previousTtr} auf ${change.currentTtr} geändert.`
},
dataForUser: (user) => {
const change = [...byPlayer.values()].find(entry => userMatchesPlayer(user, entry.playerName))
return {
previousTtr: change.previousTtr,
currentTtr: change.currentTtr,
notificationId: notificationIdFor(`ttr:${change.playerName}:${change.previousTtr}:${change.currentTtr}`)
}
},
failureLabel: 'FCM TTR-Änderungs-Push'
})
}
export async function sendTestPushToUser(userId) {
return sendPushToUsers({
title: 'Harheimer TC: Push-Test',
body: 'Diese Test-Benachrichtigung wurde erfolgreich vom CMS ausgelöst.',
data: {
type: 'test',
notificationId: notificationIdFor(`test:${userId}:${Date.now()}`)
},
predicate: user => user?.id === userId,
failureLabel: 'FCM Test-Push'
})
}