BLZ-Bankdaten: Laufzeit-Auto-Update ins Volume + Einstellungen-Seite

Statt npm-Rebuild-Wartung aktualisiert sich der Bankleitzahlen-Datensatz
jetzt zur Laufzeit. Ein Scheduler (taeglich 03:30 + Catch-up 90s) prueft
gemaess konfigurierbarem Intervall und laedt current.json/next.json von
npm/jsDelivr (Paket bankdata-germany) in das neue Bind-Mount-Volume
BANKDATA_DIR (./data/bankdata -> /app/bankdata).

Lookup bevorzugt den Volume-Datensatz vor den ins Image gebackenen Daten
(Fallback). Es wird kein Fremdcode ausgefuehrt - nur JSON gelesen und die
current+next-Delta-Logik nachgebaut. Validierung (>=1000 Eintraege, Format)
+ atomarer Write (tmp+rename) schuetzen den guten Stand vor Muell.

Datenschutz: Der Updater sendet keine Kundendaten, laedt nur eine
oeffentliche Datendatei; abschaltbar; bei Fehler/ohne Egress greift Builtin.

Neue Einstellungen-Seite /settings/bank-data zeigt Datenstand, Update-
Verfuegbarkeit und bietet "Jetzt aktualisieren" + Auto-Update-Schalter +
Intervall. Endpoints GET /api/settings/blz, POST /api/settings/blz/update-now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 13:15:07 +02:00
co-authored by Claude Opus 4.8
parent 73bd72bd9f
commit 91fbe12299
16 changed files with 788 additions and 7 deletions
@@ -1,13 +1,14 @@
import { Response } from 'express';
import { isValidIBAN } from 'ibantools';
import { bankDataByIBAN } from 'bankdata-germany';
import * as blzData from '../services/blzData.service.js';
import { ApiResponse, AuthRequest } from '../types/index.js';
/**
* IBAN-Lookup: prüft die Prüfziffer (mod-97, offline über ibantools) und liefert
* für deutsche IBANs BIC und Banknamen aus der Bundesbank-Bankleitzahlen-
* datei (offline über bankdata-germany). Die IBAN verlässt NICHT den Server; es
* findet KEIN externer Request statt. Zurückgegeben werden nur öffentliche
* datei (offline; siehe blzData.service Volume-Datensatz bevorzugt, sonst die
* ins Image gebackenen Daten). Die IBAN verlässt NICHT den Server; es findet
* KEIN externer Request statt. Zurückgegeben werden nur öffentliche
* Bankverzeichnis-Daten (BIC/Name), keine kundenbezogenen Informationen.
*
* Antwortformen (immer HTTP 200, sofern eine IBAN übergeben wurde):
@@ -32,7 +33,7 @@ export async function lookupIban(req: AuthRequest, res: Response): Promise<void>
}
const country = iban.slice(0, 2);
const bank = country === 'DE' ? bankDataByIBAN(iban) : null;
const bank = country === 'DE' ? blzData.lookupByIban(iban) : null;
res.json({
success: true,