c703d87a1c
- ownerUserId (NULL = gemeinsam, sonst persoenlich) mit Zeilenschutz nach Muster SearchProvider - GET nur gemeinsame + eigene, fremde persoenliche Eintraege 404 - POST fuer jeden Benutzer, shared nur fuer Administratoren (403) - PATCH/DELETE: persoenlich nur Besitzer, gemeinsam nur Administrator - Zugriffsklassifikation nachgemessen: 61/223/6 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
ForbiddenException,
|
|
Get,
|
|
Param,
|
|
Patch,
|
|
Post,
|
|
Req,
|
|
} from '@nestjs/common';
|
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
|
import type { AuthenticatedRequest, AuthUser } from '../auth/types/auth-user';
|
|
import { CustomModulesService } from './custom-modules.service';
|
|
import { CreateCustomModuleDto, UpdateCustomModuleDto } from './dto/custom-module.dto';
|
|
|
|
/**
|
|
* Eigene Module (quick-260929-9wc, erweitert in quick-260929-dzu). Jeder
|
|
* angemeldete Benutzer darf lesen und eigene (persoenliche) Eintraege anlegen,
|
|
* aendern und loeschen; gemeinsame Eintraege (`shared: true`) darf nur ein
|
|
* Administrator anlegen, aendern und loeschen — diese Rollenentscheidung trifft
|
|
* der Dienst, weil sie vom Eintrag abhaengt (gemeinsam oder persoenlich), nicht
|
|
* von der Route. Deshalb tragen die Routen kein `@Roles`. Kein `@UseModule`:
|
|
* eigene Module haengen an keiner Modul-Aktivierung. `tenantId` kommt
|
|
* ausschliesslich aus `req.tenantId` (gesetzt vom `TenantGuard`), der Benutzer
|
|
* aus dem Token.
|
|
*
|
|
* ROUTEN-REIHENFOLGE: NestJS bildet Routen in Deklarationsreihenfolge ab.
|
|
* Jede kuenftige statische GET-Route MUSS ueber `getOne` (`@Get(':id')`)
|
|
* stehen, sonst faengt `:id` sie ab (404-Shadowing); der Controller-Test
|
|
* haelt die Reihenfolge von `list` vor `getOne` fest.
|
|
*/
|
|
@Controller('custom-modules')
|
|
export class CustomModulesController {
|
|
constructor(private readonly service: CustomModulesService) {}
|
|
|
|
private requireTenantId(req: AuthenticatedRequest): string {
|
|
const tenantId = req.tenantId;
|
|
if (!tenantId) {
|
|
throw new ForbiddenException('Kein Mandantenkontext');
|
|
}
|
|
return tenantId;
|
|
}
|
|
|
|
@Get()
|
|
async list(@Req() req: AuthenticatedRequest, @CurrentUser() user: AuthUser) {
|
|
return this.service.list(this.requireTenantId(req), user);
|
|
}
|
|
|
|
@Get(':id')
|
|
async getOne(
|
|
@Req() req: AuthenticatedRequest,
|
|
@CurrentUser() user: AuthUser,
|
|
@Param('id') id: string,
|
|
) {
|
|
return this.service.getOne(this.requireTenantId(req), user, id);
|
|
}
|
|
|
|
@Post()
|
|
async create(
|
|
@Req() req: AuthenticatedRequest,
|
|
@CurrentUser() user: AuthUser,
|
|
@Body() dto: CreateCustomModuleDto,
|
|
) {
|
|
return this.service.create(this.requireTenantId(req), user, dto);
|
|
}
|
|
|
|
@Patch(':id')
|
|
async update(
|
|
@Req() req: AuthenticatedRequest,
|
|
@CurrentUser() user: AuthUser,
|
|
@Param('id') id: string,
|
|
@Body() dto: UpdateCustomModuleDto,
|
|
) {
|
|
return this.service.update(this.requireTenantId(req), user, id, dto);
|
|
}
|
|
|
|
@Delete(':id')
|
|
async remove(
|
|
@Req() req: AuthenticatedRequest,
|
|
@CurrentUser() user: AuthUser,
|
|
@Param('id') id: string,
|
|
) {
|
|
return this.service.remove(this.requireTenantId(req), user, id);
|
|
}
|
|
}
|