fix(mitglieder): improve Fahrgenehmigungen labels, pagination, and AT20 sync

This commit is contained in:
Matthias Hochmeister
2026-04-18 18:00:54 +02:00
parent e1c7f44e56
commit 26df8b427e
5 changed files with 54 additions and 22 deletions

View File

@@ -216,6 +216,40 @@ class AtemschutzService {
}
}
// =========================================================================
// SYNC LEHRGANG FROM FDISK COURSES (AT20)
// =========================================================================
/**
* Scans the ausbildung table for AT20 courses with erfolgscode = 'mit Erfolg'
* and upserts atemschutz_traeger records accordingly:
* - No record: creates one with atemschutz_lehrgang=true + lehrgang_datum
* - Record exists, lehrgang false: sets lehrgang=true + date (if unset)
* - Record exists, lehrgang already true: no-op (preserves manual data)
*/
async syncLehrgangFromKurse(): Promise<{ processed: number }> {
try {
const result = await pool.query(`
INSERT INTO atemschutz_traeger (id, user_id, atemschutz_lehrgang, lehrgang_datum)
SELECT uuid_generate_v4(), a.user_id, true, MIN(a.kurs_datum)
FROM ausbildung a
WHERE a.kurs_kurzbezeichnung = 'AT20'
AND a.erfolgscode = 'mit Erfolg'
GROUP BY a.user_id
ON CONFLICT (user_id) DO UPDATE
SET atemschutz_lehrgang = true,
lehrgang_datum = COALESCE(atemschutz_traeger.lehrgang_datum, EXCLUDED.lehrgang_datum),
updated_at = NOW()
`);
const processed = result.rowCount ?? 0;
logger.info('AT20 Atemschutz-Sync abgeschlossen', { processed });
return { processed };
} catch (error) {
logger.error('AtemschutzService.syncLehrgangFromKurse fehlgeschlagen', { error });
throw new Error('AT20 Atemschutz-Sync fehlgeschlagen');
}
}
// =========================================================================
// EXPIRING CERTIFICATIONS
// =========================================================================