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:
2026-09-21 16:19:16 +02:00
parent 8d845e732e
commit b188946e31
24 changed files with 147 additions and 148 deletions
+6 -6
View File
@@ -65,7 +65,7 @@ export class FavoritesService {
async list(tenantId: string, userId: string, widgetId: string) {
if (!widgetId) throw new BadRequestException('widgetId is required');
const tenantPrisma = forTenant(this.prisma, tenantId, userId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId, userId);
return tenantPrisma.favoriteLink.findMany({
where: { userId, widgetId },
orderBy: [{ position: 'asc' }, { title: 'asc' }],
@@ -79,7 +79,7 @@ export class FavoritesService {
* If iconUrl is not provided, triggers server-side icon discovery with SSRF protection.
*/
async create(tenantId: string, userId: string, dto: CreateFavoriteDto) {
const tenantPrisma = forTenant(this.prisma, tenantId, userId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId, userId);
// T-GWH-05: der Fremdschluessel prueft an der Zeilenschutz-Regel von
// WidgetInstance vorbei (Aufgabe 1, Pruefung 7) — ohne diesen Riegel
@@ -123,7 +123,7 @@ export class FavoritesService {
* Accepts null as an explicit value for iconUrl (clears stored icon).
*/
async update(tenantId: string, id: string, userId: string, dto: UpdateFavoriteDto) {
const tenantPrisma = forTenant(this.prisma, tenantId, userId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId, userId);
const link = await tenantPrisma.favoriteLink.findUnique({ where: { id } });
if (!link || link.userId !== userId) {
@@ -164,7 +164,7 @@ export class FavoritesService {
* Verifies userId ownership before deleting (T-08-06).
*/
async remove(tenantId: string, id: string, userId: string) {
const tenantPrisma = forTenant(this.prisma, tenantId, userId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId, userId);
const link = await tenantPrisma.favoriteLink.findUnique({ where: { id } });
if (!link || link.userId !== userId) {
@@ -210,7 +210,7 @@ export class FavoritesService {
throw new BadRequestException('ids must match the favorites of this widget exactly');
}
return withTenantTransaction(this.prisma, tenantId, async (tx: any) => {
return withTenantTransaction(this.prisma, tenantId, async (tx) => {
const existing = await tx.favoriteLink.findMany({
where: { userId, widgetId: dto.widgetId },
select: { id: true },
@@ -258,7 +258,7 @@ export class FavoritesService {
id: string,
userId: string,
): Promise<{ contentType: string; body: Buffer }> {
const tenantPrisma = forTenant(this.prisma, tenantId, userId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId, userId);
const link = await tenantPrisma.favoriteLink.findUnique({ where: { id } });
if (!link || link.userId !== userId || !link.iconUrl) {