import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseUUIDPipe, Post, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiSecurity, ApiTags } from '@nestjs/swagger'; import { CurrentUser } from '../decorators/current-user.decorator'; import { RequiresFeature } from '../decorators/requires-feature.decorator'; import { FeatureFlagGuard } from '../guards/feature-flag.guard'; import { ApiKeysService } from './api-keys.service'; import { CreateApiKeyDto, ApiKeyDto, CreateApiKeyResultDto } from '../dto/api-key.dto'; @ApiTags('API Keys') @ApiBearerAuth() @ApiSecurity('x-api-key') @UseGuards(FeatureFlagGuard) @RequiresFeature('api_access') @Controller('api-keys') export class ApiKeysController { constructor(private readonly apiKeysService: ApiKeysService) {} @Post() @ApiOperation({ summary: 'Générer une nouvelle clé API', description: 'Crée une clé API pour accès programmatique. La clé complète est retournée **une seule fois** — conservez-la immédiatement. Réservé aux abonnements Gold et Platinium.', }) @ApiResponse({ status: 201, description: 'Clé créée avec succès. La clé complète est dans le champ `fullKey`.', type: CreateApiKeyResultDto, }) @ApiResponse({ status: 403, description: 'Abonnement Gold ou Platinium requis' }) async create( @CurrentUser() user: { id: string; organizationId: string }, @Body() dto: CreateApiKeyDto ): Promise { return this.apiKeysService.generateApiKey(user.id, user.organizationId, dto); } @Get() @ApiOperation({ summary: 'Lister les clés API', description: "Retourne toutes les clés API de l'organisation. Les clés complètes ne sont jamais exposées — uniquement le préfixe.", }) @ApiResponse({ status: 200, type: [ApiKeyDto] }) async list(@CurrentUser() user: { organizationId: string }): Promise { return this.apiKeysService.listApiKeys(user.organizationId); } @Delete(':id') @HttpCode(HttpStatus.NO_CONTENT) @ApiOperation({ summary: 'Révoquer une clé API', description: 'Désactive immédiatement la clé API. Cette action est irréversible.', }) @ApiResponse({ status: 204, description: 'Clé révoquée' }) @ApiResponse({ status: 404, description: 'Clé introuvable' }) async revoke( @CurrentUser() user: { organizationId: string }, @Param('id', ParseUUIDPipe) keyId: string ): Promise { return this.apiKeysService.revokeApiKey(keyId, user.organizationId); } }