feat(i18n): add scripts for locale translation and patching
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 45s

- Implemented `fill-de-extended-gaps.js` to fill missing billing/orders keys in de-extended from de.
- Created `fill-i18n-deep.py` for deep translation of locale JSONs using deep-translator with fallback options.
- Added `fill-i18n-locales.js` to translate locale JSONs and write overrides for untranslated keys.
- Introduced `fix-en-leaks.py` to translate keys that still match the en-US merge, addressing English leaks.
- Developed `patch-de-ch-swiss.js` to replace 'ß' with 'ss' in de-CH.json without deleting existing entries.
- Created `patch-en-gb-au.js` to apply UK/AU spelling corrections in en-GB and en-AU locales.
- Added shell scripts `run-fix-en-leaks.sh` and `run-i18n-deep-fill.sh` for sequential execution of translation tasks.
- Implemented `update-i18n-todo-stats.js` to update statistics in the I18N_TODO.md file based on translation completeness.
This commit is contained in:
Torsten Schulz (local)
2026-05-15 15:52:54 +02:00
parent 320010b94e
commit eb54b4f7cf
54 changed files with 58003 additions and 30665 deletions

View File

@@ -2,7 +2,6 @@ import express from 'express';
import {
getTournaments,
addTournament,
addMiniChampionship,
updateTournament,
addParticipant,
getParticipants,
@@ -19,22 +18,17 @@ import {
manualAssignGroups,
resetGroups,
resetMatches,
cleanupOrphanedMatches,
removeParticipant,
updateParticipantSeeded,
setParticipantGaveUp,
deleteMatchResult,
reopenMatch,
deleteKnockoutMatches,
setMatchActive,
setMatchTableNumber,
addExternalParticipant,
getExternalParticipants,
removeExternalParticipant,
updateExternalParticipantSeeded,
setExternalParticipantGaveUp,
getTournamentClasses,
getInternalTournamentStats,
addTournamentClass,
updateTournamentClass,
deleteTournamentClass,
@@ -46,7 +40,6 @@ import {
updatePairing,
deletePairing,
} from '../controllers/tournamentController.js';
import { mergeClassesIntoPool, resetPool } from '../controllers/tournamentController.js';
import {
getStages,
upsertStages,
@@ -56,31 +49,23 @@ import { authenticate } from '../middleware/authMiddleware.js';
const router = express.Router();
router.get('/internal-stats/:clubId', authenticate, getInternalTournamentStats);
router.post('/participant', authenticate, addParticipant);
router.post('/participants', authenticate, getParticipants);
router.delete('/participant', authenticate, removeParticipant);
router.put('/participant/:clubId/:tournamentId/:participantId/seeded', authenticate, updateParticipantSeeded);
router.put('/participant/:clubId/:tournamentId/:participantId/gave-up', authenticate, setParticipantGaveUp);
router.post('/modus', authenticate, setModus);
router.post('/groups/reset', authenticate, resetGroups);
router.post('/matches/reset', authenticate, resetMatches);
router.post('/matches/cleanup-orphaned', authenticate, cleanupOrphanedMatches);
router.put('/groups', authenticate, createGroups);
router.post('/groups/create', authenticate, createGroupsPerClass);
router.post('/groups', authenticate, fillGroups);
router.post('/matches/create', authenticate, createGroupMatches);
// Pools
router.post('/pools/merge', authenticate, mergeClassesIntoPool);
router.post('/pools/reset', authenticate, resetPool);
router.get('/groups', authenticate, getGroups);
router.post('/match/result', authenticate, addMatchResult);
router.delete('/match/result', authenticate, deleteMatchResult);
router.post("/match/reopen", authenticate, reopenMatch);
router.post('/match/finish', authenticate, finishMatch);
router.put('/match/:clubId/:tournamentId/:matchId/active', authenticate, setMatchActive);
router.put('/match/:clubId/:tournamentId/:matchId/table', authenticate, setMatchTableNumber);
router.get('/matches/:clubId/:tournamentId', authenticate, getTournamentMatches);
router.post('/knockout', authenticate, startKnockout);
router.delete("/matches/knockout", authenticate, deleteKnockoutMatches);
@@ -93,7 +78,6 @@ router.post('/external-participant', authenticate, addExternalParticipant);
router.post('/external-participants', authenticate, getExternalParticipants);
router.delete('/external-participant', authenticate, removeExternalParticipant);
router.put('/external-participant/:clubId/:tournamentId/:participantId/seeded', authenticate, updateExternalParticipantSeeded);
router.put('/external-participant/:clubId/:tournamentId/:participantId/gave-up', authenticate, setExternalParticipantGaveUp);
// Tournament Classes
router.get('/classes/:clubId/:tournamentId', authenticate, getTournamentClasses);
@@ -113,9 +97,6 @@ router.get('/stages', authenticate, getStages);
router.put('/stages', authenticate, upsertStages);
router.post('/stages/advance', authenticate, advanceStage);
// Minimeisterschaft anlegen (vor :clubId, damit 'mini' nicht als clubId matcht)
router.post('/mini', authenticate, addMiniChampionship);
// Muss NACH allen festen Pfaden stehen, sonst matcht z.B. '/stages' als clubId='stages'
router.get('/:clubId', authenticate, getTournaments);
router.post('/', authenticate, addTournament);