refactor(quick-260921-bi2): maschinelle Lint-Fixe und toten Code abbauen
- Aufgabe 2: vier sichere Biome-Regeln (useImportType pfadgebunden auf apps/web+packages, noUselessEscapeInRegex, useConst, useExponentiationOperator) sowie fuenf ungesicherte Regeln (useNodejsImportProtocol, useLiteralKeys, useOptionalChain, useTemplate, useParseIntRadix) angewendet und den gesamten Diff von Hand gelesen (ldap.service.ts zeichenweise gegen Gross-/Kleinschreibung der AD-Merkmale, auth.service.ts/jwt.strategy.ts gegen Durchwinken bei fehlender Sitzung geprueft) - noUselessSwitchCase bleibt bewusst stehen (tender-normalizer.service.ts:60, die Fallmarke dokumentiert Absicht) - Toter Code (D-03): fuenf folgenlose Auffangvariablen entfernt, eine nicht benutzte Funktion (forSystemQuery, Pruefskript) entfernt, ein positionsgebundener Dekoratorparameter umbenannt (current-user.decorator.ts), fuenf Symptomfunde entfernt und als Folgeaufgaben zu melden (siehe unten) - Sechs weitere, im Plan nicht namentlich gelistete aber gleich-kategorische Dead-Code-Fundstellen in Testdateien zusaetzlich bereinigt (groups.service.spec.ts, cert-manager.test.tsx, ldap.service.spec.ts, prisma-tenant.extension.spec.ts x3) — noetig, um die vom Plan selbst verlangten Nullstaende bei noUnusedVariables/ noUnusedImports/noUnusedFunctionParameters zu erreichen Dekoratordaten aus apps/api unveraendert (593 Zeilen, sha256 6e1583f1...). Endstand 620 Befunde (541 echt, 79 Test) statt der im Plan geschaetzten 621/542 — eine Differenz von 1, weil das Streichen des Namens aus `catch (e: any)` in calendar.service.ts (Symptom-Fix) den dort ebenfalls gemeldeten noExplicitAny-Befund miteliminiert; das ist eine erwuenschte Nebenwirkung, keine Regression. Fehlerstufe 0, beide Testlaeufe punktgleich gruen (69/1124, 66/459), pnpm type-check 4/4, pnpm lint --force 5/5. Folgeaufgaben aus D-03 (nicht in diesem Vorgang behoben): - force-password-change.interceptor.ts: Freigabeliste prueft nur den Pfad, nicht die HTTP-Methode - change-password/page.tsx: nach erzwungenem Wechsel bleibt die Person auf der Seite stehen (keine Weiterleitung, keine Aktualisierung der Benutzerablage) - VehicleTable.tsx: Loeschschaltflaeche hat keinen Besetztzustand, laesst sich doppelt ausloesen - SplitTab.tsx: downloadAllAsZip erhielt eine ungenutzte Uebersetzungsfunktion, Hinweis auf fest verdrahtete Texte im Zip-Pfad Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as XLSX from 'xlsx';
|
||||
import { ExportRow } from './dkv.types';
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ export class DkvParserService {
|
||||
let text: string;
|
||||
try {
|
||||
text = await this.extractText(buffer);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
this.logger.error('DKV PDF text extraction failed');
|
||||
throw new Error('DKV invoice parsing failed — text extraction error');
|
||||
}
|
||||
@@ -98,7 +98,7 @@ export class DkvParserService {
|
||||
// Anchor on VEHICLE: marker — each block extends until next VEHICLE: or end
|
||||
// Kennzeichen format: "GP-JL 728E", "GP ML 720", etc.
|
||||
const vehicleBlockPattern =
|
||||
/VEHICLE:\s+([A-Z0-9 ._\-]+?)\s+CARD NO\.:\s+(\S+)([\s\S]*?)(?=VEHICLE:|$)/g;
|
||||
/VEHICLE:\s+([A-Z0-9 ._-]+?)\s+CARD NO\.:\s+(\S+)([\s\S]*?)(?=VEHICLE:|$)/g;
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = vehicleBlockPattern.exec(text)) !== null) {
|
||||
|
||||
@@ -133,7 +133,7 @@ function parseDkvText(text: string): DkvVehicleBlock[] {
|
||||
// Anchor on VEHICLE: marker — each block extends until next VEHICLE: or end of text
|
||||
// Kennzeichen can contain letters, digits, hyphens, spaces, dots (e.g. "GP-JL 728E")
|
||||
const vehicleBlockPattern =
|
||||
/VEHICLE:\s+([A-Z0-9 ._\-]+?)\s+CARD NO\.:\s+(\S+)([\s\S]*?)(?=VEHICLE:|$)/g;
|
||||
/VEHICLE:\s+([A-Z0-9 ._-]+?)\s+CARD NO\.:\s+(\S+)([\s\S]*?)(?=VEHICLE:|$)/g;
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = vehicleBlockPattern.exec(text)) !== null) {
|
||||
|
||||
@@ -219,7 +219,7 @@ export class DkvController {
|
||||
) {
|
||||
const tenantId = this._requireTenant(req);
|
||||
|
||||
if (!file || !file.buffer) {
|
||||
if (!file?.buffer) {
|
||||
throw new BadRequestException('No CSV file uploaded (field name must be "file")');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as fs from 'fs';
|
||||
import * as fs from 'node:fs';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { DkvService } from './dkv.service';
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { CryptoService } from '../crypto/crypto.service';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { forSystem, forTenant } from '../prisma/prisma-tenant.extension';
|
||||
@@ -513,7 +513,7 @@ export class DkvService {
|
||||
smtpError = (err as Error).message;
|
||||
this.logger.warn(`DKV SMTP send attempt ${attempt}/3 failed: ${smtpError}`);
|
||||
if (attempt < 3) {
|
||||
await _delay(Math.pow(2, attempt) * 1000); // 2s, 4s
|
||||
await _delay(2 ** attempt * 1000); // 2s, 4s
|
||||
} else {
|
||||
smtpStatus = 'Versand fehlgeschlagen';
|
||||
// D-16: file stays locally available for manual download
|
||||
@@ -707,7 +707,7 @@ export class DkvService {
|
||||
filename.includes('/') ||
|
||||
filename.includes('\\') ||
|
||||
filename.includes('..') ||
|
||||
!/^(RG-DKV-|DKV_)[\w\-]+\.xlsx$/.test(filename)
|
||||
!/^(RG-DKV-|DKV_)[\w-]+\.xlsx$/.test(filename)
|
||||
) {
|
||||
throw new BadRequestException('Invalid export filename');
|
||||
}
|
||||
@@ -806,9 +806,9 @@ export class DkvService {
|
||||
): string {
|
||||
if (fromPdf) return fromPdf.replace(/\//g, '-');
|
||||
// DKV email subjects carry the invoice number with slashes: "26/650869002/002"
|
||||
const m = subject?.match(/(\d{2}[\/\-]\d{9}[\/\-]\d{3})/);
|
||||
const m = subject?.match(/(\d{2}[/-]\d{9}[/-]\d{3})/);
|
||||
if (m?.[1]) return m[1].replace(/\//g, '-');
|
||||
return `email-${String(uid).replace(/[^a-zA-Z0-9\-]/g, '_')}`;
|
||||
return `email-${String(uid).replace(/[^a-zA-Z0-9-]/g, '_')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -880,5 +880,5 @@ function _formatDateYYMMDD(date: string): string {
|
||||
* Example: "GP JL 740E" == "GP-JL 740E" == "GPJL740E" after normalization.
|
||||
*/
|
||||
function _normalizeKennzeichen(k: string): string {
|
||||
return k.toUpperCase().replace(/[\s\-\.]/g, '');
|
||||
return k.toUpperCase().replace(/[\s\-.]/g, '');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user