refactor(quick-260921-m34): Aufgabe 1 - Mandantenbindung entzaubert, 105 unnoetige any-Zusicherungen entfernt
- prisma-tenant.extension.ts: (prisma as any) und die Handannotation an
$allOperations in forTenant()/forSystem() entfernt; Kopfkommentar
unveraendert. .then((results: any[]) => ...) auf unknown[] umgestellt.
- 105 Aufrufstellen `const X = forTenant(...) as any` / `forSystem(...) as
any` von der Zusicherung befreit, Zuweisungsform woertlich erhalten
(rls-access-inventory.spec.ts bleibt scharf, 30/30 gruen einzeln
geprueft).
- withTenantTransaction(): Prisma.TransactionClient fuer tx probiert,
gemessen verworfen - bricht das Testdoppel in
prisma-tenant.extension.spec.ts (TS2322 auf einem absichtlich
unvollstaendigen Fake-Objekt). tx bleibt any, mit Begruendung am Typ.
- Gefolge des jetzt getypten Klienten entfernt: any[]-Annotationen und
.map((x: any) => ...) in groups.service.ts, module-grants.service.ts,
dkv.service.ts, ldap-config.service.ts, tenders.controller.ts:270.
- Befund (D-03): tender-matching.service.ts:159 trug eine Handannotation
(match: { tender: unknown }), die den Wert nur deshalb auf unknown
verengte, um TS7006 unter dem alten any-Klienten zu vermeiden - mit dem
getypten Klienten war das falsch. Annotation geloescht, kein Ersatz
durch Zusicherung.
- Zwei any bleiben gezielt in groups.service.ts (u/a in
ensureDefaultGroup(), gefolge von tx: any) - Begruendung am Code.
noExplicitAny apps/api/src: 288 -> 149 (Schranke 155). type-check 4/4,
lint 5/5 (0 error). apps/api 72/1143 gruen, apps/web 73/531 gruen,
rls-access-inventory.spec.ts 30/30 gruen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
@@ -118,7 +118,7 @@ export class DkvService {
|
||||
* 260914-eym systemgebunden, eine Zeile je aktivem Mandanten).
|
||||
*/
|
||||
async loadConfig(tenantId: string) {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
return tenantPrisma.dkvModuleConfig.findUnique({
|
||||
where: { tenantId },
|
||||
select: CONFIG_SAFE_SELECT,
|
||||
@@ -153,7 +153,7 @@ export class DkvService {
|
||||
* (T-07-12) — der Planer braucht nur tenantId und pollIntervalMin.
|
||||
*/
|
||||
async loadActiveConfigsForScheduler() {
|
||||
const systemPrisma = forSystem(this.prisma) as any;
|
||||
const systemPrisma = forSystem(this.prisma);
|
||||
return systemPrisma.dkvModuleConfig.findMany({
|
||||
where: { isActive: true },
|
||||
select: CONFIG_SAFE_SELECT,
|
||||
@@ -171,7 +171,7 @@ export class DkvService {
|
||||
* Methode).
|
||||
*/
|
||||
async getConfigForApi(tenantId: string) {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const safe = await tenantPrisma.dkvModuleConfig.findUnique({
|
||||
where: { tenantId },
|
||||
select: CONFIG_SAFE_SELECT,
|
||||
@@ -214,7 +214,7 @@ export class DkvService {
|
||||
* Bindung als zweite Schicht bestehen.
|
||||
*/
|
||||
async saveConfig(tenantId: string, dto: DkvConfigDto) {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
let encryptedInboxCreds: string | undefined;
|
||||
|
||||
const credChanged = (dto.password && dto.password.length > 0) ||
|
||||
@@ -277,7 +277,7 @@ export class DkvService {
|
||||
* Rueckgriff auf die gespeicherten Zugangsdaten.
|
||||
*/
|
||||
async testConnection(tenantId: string, dto: DkvConfigDto): Promise<{ success: boolean; message?: string }> {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
let password: string | undefined = dto.password;
|
||||
|
||||
// If no password in DTO, fall back to the stored one
|
||||
@@ -362,7 +362,7 @@ export class DkvService {
|
||||
private async _runPipeline(tenantId: string): Promise<void> {
|
||||
// Load raw config (need encryptedInboxCreds for decryption).
|
||||
// Mandantengebunden (260909-mir).
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const config = await tenantPrisma.dkvModuleConfig.findUnique({ where: { tenantId } });
|
||||
if (!config) {
|
||||
this.logger.warn(`DKV processInbox: no config for tenant ${tenantId}`);
|
||||
@@ -448,7 +448,7 @@ export class DkvService {
|
||||
// Mandantengebunden (260909-mir): EIN gebundener Klient fuer beide
|
||||
// dkvInvoiceHistory.create()-Aufrufe dieser Methode (Erfolgsfall UND
|
||||
// Zerlegungsfehler-Fall).
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
|
||||
// D-10: Up to 3 parse retries
|
||||
let parseResult: Awaited<ReturnType<typeof this.parser.parsePdf>> | null = null;
|
||||
@@ -546,7 +546,7 @@ export class DkvService {
|
||||
// ─── Vehicle CRUD ────────────────────────────────────────────────────────────
|
||||
|
||||
async listVehicles(tenantId: string) {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
return tenantPrisma.dkvVehicleMaster.findMany({
|
||||
where: { tenantId },
|
||||
orderBy: { kennzeichen: 'asc' },
|
||||
@@ -554,7 +554,7 @@ export class DkvService {
|
||||
}
|
||||
|
||||
async createVehicle(tenantId: string, dto: CreateVehicleDto) {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
return tenantPrisma.dkvVehicleMaster.create({
|
||||
data: { tenantId, ...dto },
|
||||
});
|
||||
@@ -571,7 +571,7 @@ export class DkvService {
|
||||
* Schreibzugriff dahinter waere genau die Luecke, nicht die Loesung.
|
||||
*/
|
||||
async updateVehicle(tenantId: string, id: string, dto: UpdateVehicleDto) {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const existing = await tenantPrisma.dkvVehicleMaster.findFirst({
|
||||
where: { id, tenantId },
|
||||
});
|
||||
@@ -581,7 +581,7 @@ export class DkvService {
|
||||
|
||||
/** Mandantengebunden (260909-mir, Befund G) — siehe updateVehicle() oben. */
|
||||
async deleteVehicle(tenantId: string, id: string): Promise<{ deleted: boolean }> {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const existing = await tenantPrisma.dkvVehicleMaster.findFirst({
|
||||
where: { id, tenantId },
|
||||
});
|
||||
@@ -611,7 +611,7 @@ export class DkvService {
|
||||
csvText: string,
|
||||
mode: 'merge' | 'replace',
|
||||
): Promise<{ imported: number; mode: string }> {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const vehicles = _parseVehicleCsv(csvText);
|
||||
if (vehicles.length === 0) {
|
||||
throw new BadRequestException(
|
||||
@@ -661,7 +661,7 @@ export class DkvService {
|
||||
page: number;
|
||||
limit: number;
|
||||
}> {
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const skip = (page - 1) * limit;
|
||||
const [items, total] = await Promise.all([
|
||||
tenantPrisma.dkvInvoiceHistory.findMany({
|
||||
@@ -714,7 +714,7 @@ export class DkvService {
|
||||
|
||||
// Stage 2 (NEW, 260909-mir): the ownership gate. A bound read — the
|
||||
// only tenant-scoped statement of who this file belongs to.
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const owningHistoryRow = await tenantPrisma.dkvInvoiceHistory.findFirst({
|
||||
where: { tenantId, exportFilename: filename },
|
||||
});
|
||||
@@ -751,8 +751,8 @@ export class DkvService {
|
||||
vehicleFormatString: string,
|
||||
): Promise<{ lieferdatum: string; fahrzeug: string; fahrer: string; ort: string; kilometerstand: number | null }[]> {
|
||||
// Batch load vehicle master to avoid N+1 queries
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
|
||||
const masters: any[] = await tenantPrisma.dkvVehicleMaster.findMany({ where: { tenantId } });
|
||||
const tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
const masters = await tenantPrisma.dkvVehicleMaster.findMany({ where: { tenantId } });
|
||||
// Normalize keys: DKV PDF may omit hyphens or use spaces ("GP JL 740E" vs "GP-JL 740E")
|
||||
const masterMap = new Map(masters.map((m) => [_normalizeKennzeichen(m.kennzeichen), m]));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user