round30: alle drei Scanner als Hintergrund-Job, Dienst-Duplikate strukturell verhindert (Migration+Constraint+Geraete-Sperre), zweiter Erkennungsversuch bei leerem Ersttreffer

This commit is contained in:
2026-07-24 15:14:00 +02:00
parent 2106c17301
commit 87fed21348
7 changed files with 308 additions and 140 deletions

View File

@@ -1,4 +1,4 @@
export type ScanJobType = "devices" | "apis";
export type ScanJobType = "devices" | "apis" | "fritzbox";
export interface ScanJobProgress {
current: number;
@@ -80,3 +80,23 @@ export function failJob(type: ScanJobType, error: string): void {
const job = jobs.get(type) ?? emptyStatus();
jobs.set(type, { ...job, running: false, lastError: error, cancelRequested: false });
}
/**
* Sperrt ein einzelnes Gerät gegen ÜBERLAPPENDE Scans - unabhängig davon, ob
* der Scan über den Einzelgerät-Endpunkt oder als Teil des Sammel-Scans
* ("Alle Geräte scannen") läuft. Ohne das könnten zwei gleichzeitige Scans
* desselben Geräts beide unabhängig voneinander denselben neuen Dienst
* anlegen wollen (siehe UNIQUE-Index in client.ts als zusätzliches
* Sicherheitsnetz auf Datenbankebene).
*/
const devicesCurrentlyScanning = new Set<string>();
export function tryLockDevice(deviceId: string): boolean {
if (devicesCurrentlyScanning.has(deviceId)) return false;
devicesCurrentlyScanning.add(deviceId);
return true;
}
export function unlockDevice(deviceId: string): void {
devicesCurrentlyScanning.delete(deviceId);
}