feat(quick-261003-387): Modulkategorien je Organisation - Tabellen, Grundbestand, Lese-Endpunkt bis in die Seitenleiste

- Tabellen ModuleCategory und ModuleCategoryPlacement mit Zeilenschutz, Spalte CustomModule.sortOrder
- Dienst legt den Grundbestand beim ersten Lesen an, legt die wirksame Kategorie ueber Modullisten
- GET /module-categories, PATCH :key (nur Administratoren), /modules/active liefert wirksame Kategorie
- Seitenleiste ordnet Gruppen und Eintraege nach Kategorienspeicher, zeigt umbenannte Namen

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-03 02:33:59 +02:00
parent 53a49a109f
commit 8ec116c75a
21 changed files with 1052 additions and 16 deletions
@@ -11,6 +11,7 @@ import { Role } from '@prisma/client';
import type { AuthenticatedRequest } from '../auth/types/auth-user';
import { Roles } from '../auth/decorators/roles.decorator';
import { RolesGuard } from '../auth/guards/roles.guard';
import { ModuleCategoriesService } from '../module-categories/module-categories.service';
import { ModuleAccessService } from './module-access.service';
import { ModuleRegistryService } from './module-registry.service';
@@ -32,6 +33,7 @@ export class ModuleRegistryController {
constructor(
private readonly moduleRegistryService: ModuleRegistryService,
private readonly moduleAccessService: ModuleAccessService,
private readonly moduleCategoriesService: ModuleCategoriesService,
) {}
/**
@@ -60,7 +62,10 @@ export class ModuleRegistryController {
if (!tenantId || !userId || !role) {
throw new ForbiddenException('No user context');
}
return this.moduleAccessService.findAccessibleModules(tenantId, userId, role);
const modules = await this.moduleAccessService.findAccessibleModules(tenantId, userId, role);
// quick-261003-387: wirksame Kategorie + Reihenfolge der Organisation
// (Zuordnung schlaegt Manifest-Kategorie), sortiert fuer die Seitenleiste.
return this.moduleCategoriesService.applyToModules(tenantId, modules);
}
/**
@@ -1,4 +1,5 @@
import { Module } from '@nestjs/common';
import { ModuleCategoriesModule } from '../module-categories/module-categories.module';
import { ModuleAccessService } from './module-access.service';
import { ModuleRegistryController } from './module-registry.controller';
import { ModuleRegistryService } from './module-registry.service';
@@ -19,6 +20,7 @@ import { ModuleGuard } from './module.guard';
* Plan 15-05, Grant-Services Plan 15-03) can inject and use them.
*/
@Module({
imports: [ModuleCategoriesModule],
controllers: [ModuleRegistryController],
providers: [ModuleRegistryService, ModuleAccessService, ModuleGuard],
exports: [ModuleRegistryService, ModuleAccessService, ModuleGuard],