import { Body, Controller, Delete, ForbiddenException, Get, Param, ParseUUIDPipe, Patch, Post, Query, Req, } from '@nestjs/common'; import { Request } from 'express'; import { CreateFavoriteDto } from './dto/create-favorite.dto'; import { UpdateFavoriteDto } from './dto/update-favorite.dto'; import { FavoritesService } from './favorites.service'; /** * REST controller for per-user, per-widget favorite links. * * All routes are protected by the global JwtAuthGuard + TenantGuard. * * Routes: * - GET /favorites?widgetId= — list favorites for a widget instance * - POST /favorites — create a favorite (triggers server-side icon discovery) * - PATCH /favorites/:id — update a favorite (ownership verified in service) * - DELETE /favorites/:id — delete a favorite (ownership verified in service) */ @Controller('favorites') export class FavoritesController { constructor(private readonly favoritesService: FavoritesService) {} private extractContext(req: Request) { const userId = (req as any).user?.id; const tenantId = (req as any).tenantId ?? (req as any).user?.tenantId; if (!tenantId) { throw new ForbiddenException('No tenant context'); } if (!userId) { throw new ForbiddenException('No user context'); } return { userId, tenantId }; } @Get() async list( @Query('widgetId', ParseUUIDPipe) widgetId: string, @Req() req: Request, ) { const { userId } = this.extractContext(req); return this.favoritesService.list(userId, widgetId); } @Post() async create( @Body() dto: CreateFavoriteDto, @Req() req: Request, ) { const { userId, tenantId } = this.extractContext(req); return this.favoritesService.create(userId, tenantId, dto); } @Patch(':id') async update( @Param('id') id: string, @Body() dto: UpdateFavoriteDto, @Req() req: Request, ) { const { userId } = this.extractContext(req); return this.favoritesService.update(id, userId, dto); } @Delete(':id') async remove( @Param('id') id: string, @Req() req: Request, ) { const { userId } = this.extractContext(req); return this.favoritesService.remove(id, userId); } }