refactor(quick-260921-m34): Aufgabe 3b - Prisma-nahe Formen getypt, Erkenner-Falle gemeldet

- auth.service.ts:393: (response as any).cookie war schlicht ueberfluessig.
  response ist in derselben Signatur bereits Response aus express, die
  Schwesterstelle :190 kommt ohne Zusicherung aus. Ersatzlos entfernt.
- calendar.service.ts: das lokal gebaute data-Objekt traegt jetzt
  Prisma.CalendarSourceUncheckedCreateInput bzw. ...UncheckedUpdateInput
  statt Record<string, unknown> plus Zusicherung. Damit fallen beide
  `data as any` weg, ohne dass ein Feld behauptet wird.
- user.service.ts: `let created: any` -> User (die Zuweisung steht im try,
  der catch endet ausnahmslos mit throw). `const updateData: any` wird aus
  der Signatur hergeleitet - Omit<UpdateUserInput, 'password'> plus dem
  daraus berechneten passwordHash; die Parameterform ist dafuer als
  UpdateUserInput benannt und nicht neu erfunden. `const results: any[]`
  wird Pick<User, keyof typeof PLATFORM_USER_SELECT>[], die Spaltenauswahl
  steht als Konstante daneben.
- tenant.controller.ts:69: Elementtyp aus dem hergeleitet, was die Schleife
  hineinlegt (fuenf Tenant-Spalten plus userCount).

BEFUND 3 (D-03, gemeldet, kein Verhalten betroffen) Die naheliegende
Prisma-Schreibweise Prisma.UserGetPayload<{ select: typeof X }> laesst
rls-access-inventory.spec.ts rot werden: der Erkenner zaehlt JEDE
select:-Angabe ausserhalb eines erkannten Modellaufrufs als Verstoss und
unterscheidet Typposition nicht von Aufrufposition. Gemessen beim ersten
Versuch. Der Erkenner ist die Mandantenkontrolle (T-M34-03) und wurde
NICHT aufgeweicht - stattdessen leitet der Zeilentyp ueber Pick<User, ...>
her, was ohne das Wort select auskommt. Begruendung steht am Typ.

noExplicitAny in apps/api/src: 38 -> 31. type-check 4/4, lint 5/5 (0
error), apps/api 72/1143, apps/web 73/531, rls-access-inventory 30/30.
noNonNullAssertion 56, as unknown as 33, Unterdrueckungsmarker 1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
2026-09-21 17:21:53 +02:00
parent 32591b6690
commit 3892c5f3c6
4 changed files with 72 additions and 34 deletions
+5 -4
View File
@@ -4,6 +4,7 @@ import {
Logger,
NotFoundException,
} from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { forTenant } from '../prisma/prisma-tenant.extension';
import { CryptoService } from '../crypto/crypto.service';
@@ -185,7 +186,7 @@ export class CalendarService {
// Exchange EWS servers are commonly on internal networks — SSRF check skipped for exchange type
if (dto.type !== 'exchange') await this.validateUrlNotPrivate(dto.url);
const data: Record<string, unknown> = {
const data: Prisma.CalendarSourceUncheckedCreateInput = {
userId,
tenantId,
name: dto.name,
@@ -203,7 +204,7 @@ export class CalendarService {
const tenantPrisma = forTenant(this.prisma, tenantId, userId);
const created = await tenantPrisma.calendarSource.create({
data: data as any,
data,
select: SOURCE_SAFE_SELECT,
});
@@ -234,7 +235,7 @@ export class CalendarService {
await this.validateUrlNotPrivate(dto.url);
}
const data: Record<string, unknown> = {};
const data: Prisma.CalendarSourceUncheckedUpdateInput = {};
if (dto.name !== undefined) data.name = dto.name;
if (dto.type !== undefined) data.type = dto.type;
if (dto.url !== undefined) data.url = dto.url;
@@ -252,7 +253,7 @@ export class CalendarService {
const updated = await tenantPrisma.calendarSource.update({
where: { id },
data: data as any,
data,
select: {
...SOURCE_SAFE_SELECT,
encryptedPassword: true,