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
+16 -18
View File
@@ -48,7 +48,7 @@ export class ModuleGrantsService {
groupId?: string,
userId?: string,
): Promise<void> {
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId);
if (groupId) {
const group = await tenantPrisma.group.findFirst({
where: { id: groupId, tenantId },
@@ -107,7 +107,7 @@ export class ModuleGrantsService {
// Datenbank" entfallen.
await this.assertTargetBelongsToTenant(tenantId, groupId, userId);
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId);
const activation = await tenantPrisma.tenantModuleActivation.findUnique({
where: { tenantId_moduleId: { tenantId, moduleId } },
});
@@ -166,7 +166,7 @@ export class ModuleGrantsService {
const { moduleId, groupId, userId } = data;
const target = groupId ? `group=${groupId}` : `user=${userId}`;
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId);
await tenantPrisma.moduleGrant.deleteMany({
where: {
tenantId,
@@ -189,7 +189,7 @@ export class ModuleGrantsService {
* hinweg stabil.
*/
async getMatrix(tenantId: string) {
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId);
const [activations, groups, groupGrants] = await Promise.all([
tenantPrisma.tenantModuleActivation.findMany({
where: { tenantId, isActive: true },
@@ -206,18 +206,17 @@ export class ModuleGrantsService {
]);
const modules = activations
.map((a: any) => a.module)
.map((a) => a.module)
.sort(
(a: any, b: any) =>
a.category.localeCompare(b.category) || a.name.localeCompare(b.name),
(a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name),
);
return {
modules,
groups,
grants: groupGrants.map((g: any) => ({
moduleId: g.moduleId as string,
groupId: g.groupId as string,
grants: groupGrants.map((g) => ({
moduleId: g.moduleId,
groupId: g.groupId,
})),
};
}
@@ -246,7 +245,7 @@ export class ModuleGrantsService {
async getUserAccess(tenantId: string, userId: string) {
await this.assertTargetBelongsToTenant(tenantId, undefined, userId);
const tenantPrisma = forTenant(this.prisma, tenantId) as any;
const tenantPrisma = forTenant(this.prisma, tenantId);
const [activations, groupGrants, directGrants, memberships] = await Promise.all([
tenantPrisma.tenantModuleActivation.findMany({
where: { tenantId, isActive: true },
@@ -275,9 +274,9 @@ export class ModuleGrantsService {
}),
]);
const directModuleIds = new Set(directGrants.map((g: any) => g.moduleId as string));
const directModuleIds = new Set(directGrants.map((g) => g.moduleId));
const groupNamesByModule = new Map<string, string[]>();
for (const g of groupGrants as any[]) {
for (const g of groupGrants) {
if (!g.group) continue;
const names = groupNamesByModule.get(g.moduleId) ?? [];
names.push(g.group.internalName ?? g.group.name);
@@ -285,13 +284,12 @@ export class ModuleGrantsService {
}
const modules = activations
.map((a: any) => a.module)
.map((a) => a.module)
.sort(
(a: any, b: any) =>
a.category.localeCompare(b.category) || a.name.localeCompare(b.name),
(a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name),
);
const groups = (memberships as any[])
const groups = memberships
.filter((m) => m.group)
.map((m) => ({
id: m.group.id as string,
@@ -302,7 +300,7 @@ export class ModuleGrantsService {
return {
groups,
modules: modules.map((module: any) => ({
modules: modules.map((module) => ({
module,
viaGroups: groupNamesByModule.get(module.id) ?? [],
direct: directModuleIds.has(module.id),