diff --git a/backend/src/routes/admin.routes.ts b/backend/src/routes/admin.routes.ts index 13f7f6c..763f1cc 100644 --- a/backend/src/routes/admin.routes.ts +++ b/backend/src/routes/admin.routes.ts @@ -290,6 +290,7 @@ router.delete('/cleanup/reset-buchhaltung-konten', authenticate, requirePermissi router.delete('/cleanup/reset-buchhaltung-bankkonten', authenticate, requirePermission('admin:write'), (req, res) => { req.params.resetTarget = 'reset-buchhaltung-bankkonten'; return resetHandler(req, res); }); router.delete('/cleanup/reset-checklist-history', authenticate, requirePermission('admin:write'), (req, res) => { req.params.resetTarget = 'reset-checklist-history'; return resetHandler(req, res); }); router.delete('/cleanup/reset-persoenliche-ausruestung', authenticate, requirePermission('admin:write'), (req, res) => { req.params.resetTarget = 'reset-persoenliche-ausruestung'; return resetHandler(req, res); }); +router.delete('/cleanup/reset-atemschutz', authenticate, requirePermission('admin:write'), (req, res) => { req.params.resetTarget = 'reset-atemschutz'; return resetHandler(req, res); }); router.delete('/cleanup/issues-all', authenticate, requirePermission('admin:write'), (req, res) => { req.params.resetTarget = 'issues-all'; return resetHandler(req, res); }); router.delete( @@ -334,6 +335,7 @@ const RESET_TARGETS: Record Promise<{ count: numbe 'reset-buchhaltung-konten': (c) => cleanupService.resetBuchhaltungKonten(c), 'reset-buchhaltung-bankkonten': (c) => cleanupService.resetBuchhaltungBankkonten(c), 'reset-persoenliche-ausruestung': (c) => cleanupService.resetPersoenlicheAusruestung(c), + 'reset-atemschutz': (c) => cleanupService.resetAtemschutz(c), }; const resetHandler = async (req: Request, res: Response): Promise => { diff --git a/backend/src/services/cleanup.service.ts b/backend/src/services/cleanup.service.ts index cd6ed15..601cef2 100644 --- a/backend/src/services/cleanup.service.ts +++ b/backend/src/services/cleanup.service.ts @@ -239,6 +239,18 @@ class CleanupService { return { count, deleted: true }; } + async resetAtemschutz(confirm: boolean): Promise { + if (!confirm) { + const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM atemschutz_traeger'); + return { count: rows[0].count, deleted: false }; + } + const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM atemschutz_traeger'); + const count = rows[0].count; + await pool.query('TRUNCATE atemschutz_traeger CASCADE'); + logger.info(`Cleanup: truncated atemschutz_traeger (${count} rows)`); + return { count, deleted: true }; + } + async resetPersoenlicheAusruestung(confirm: boolean): Promise { if (!confirm) { const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM persoenliche_ausruestung WHERE geloescht_am IS NULL'); diff --git a/frontend/src/components/admin/DataManagementTab.tsx b/frontend/src/components/admin/DataManagementTab.tsx index 414857d..f431e78 100644 --- a/frontend/src/components/admin/DataManagementTab.tsx +++ b/frontend/src/components/admin/DataManagementTab.tsx @@ -50,6 +50,9 @@ const TAB_CLEANUP: Record = { }; const TAB_RESET: Record = { + atemschutz: [ + { key: 'reset-atemschutz', label: 'Atemschutz-Daten zuruecksetzen', description: 'Alle Atemschutz-Eintraege (G26-Untersuchungen, Leistungstests, Lehrgaenge) fuer alle Benutzer loeschen.' }, + ], fahrzeuge: [ { key: 'reset-persoenliche-ausruestung', label: 'Persoenliche Ausruestung zuruecksetzen', description: 'Alle persoenlichen Ausruestungszuweisungen loeschen. Zuordnungen in Anfragen werden zurueckgesetzt.' }, ], @@ -82,6 +85,7 @@ const TABS = [ { key: 'system', label: 'System' }, { key: 'kalender', label: 'Kalender' }, { key: 'fahrzeuge', label: 'Fahrzeuge & Ausruestung' }, + { key: 'atemschutz', label: 'Atemschutz' }, { key: 'bestellungen', label: 'Bestellungen' }, { key: 'buchhaltung', label: 'Buchhaltung' }, { key: 'checklisten', label: 'Checklisten & Issues' },