import { Inject, Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, Req } from "@nestjs/common"; import type { Request } from "express"; import { UsersService } from "./users.service.js"; import { ZodValidate } from "../../common/pipes/zod-validation.pipe.js"; import { requireUser } from "../../common/types.js"; import { UpdateProfileDto, type UpdateProfileInput, ListUsersQuery, type ListUsersInput, RecordRecentItemDto, type RecordRecentItemInput, SavedSearchCreateDto, type SavedSearchCreateInput, SavedSearchUpdateDto, type SavedSearchUpdateInput } from "./dto.js"; @Controller("users") export class UsersController { constructor(@Inject(UsersService) private readonly users: UsersService) {} @Get("me") me(@Req() req: Request) { return this.users.getMe(requireUser(req)); } @Get("me/profile") meProfile(@Req() req: Request) { return this.users.getMe(requireUser(req)); } @Patch("me") updateMe( @Req() req: Request, @Body(ZodValidate(UpdateProfileDto)) body: UpdateProfileInput ) { return this.users.updateProfile(requireUser(req), body); } /** Workspace member listing (membership checked by the workspaces guard layer). */ @Get() list(@Query(ZodValidate(ListUsersQuery)) query: ListUsersInput, @Req() req: Request) { return this.users.listForWorkspace(query.workspaceId, query); } // ---------- T-158: activity feed (permission-scoped audit projection) ---------- @Get("me/activity") myActivity(@Req() req: Request, @Query("cursor") cursor: string | undefined, @Query("limit") limit: string | undefined) { return this.users.listMyActivity(requireUser(req), { cursor, limit }); } // ---------- T-153: recently-viewed items (per-user) ---------- /** Record a page view (upsert + bump; cap 50). */ @Put("me/recent") recordRecent(@Req() req: Request, @Body(ZodValidate(RecordRecentItemDto)) body: RecordRecentItemInput) { return this.users.recordRecentItem(requireUser(req), body); } /** The caller's recent items, newest first (cap 50). */ @Get("me/recent") listRecent(@Req() req: Request) { return this.users.listRecentItems(requireUser(req)); } // ---------- T-154: saved searches (per-user; cross-user id → 404) ---------- @Get("me/saved-searches") listSavedSearches(@Req() req: Request) { return this.users.listSavedSearches(requireUser(req)); } @Post("me/saved-searches") createSavedSearch(@Req() req: Request, @Body(ZodValidate(SavedSearchCreateDto)) body: SavedSearchCreateInput) { return this.users.createSavedSearch(requireUser(req), body); } @Get("me/saved-searches/:id") getSavedSearch(@Req() req: Request, @Param("id") id: string) { return this.users.getSavedSearch(requireUser(req), id); } @Patch("me/saved-searches/:id") updateSavedSearch( @Req() req: Request, @Param("id") id: string, @Body(ZodValidate(SavedSearchUpdateDto)) body: SavedSearchUpdateInput ) { return this.users.updateSavedSearch(requireUser(req), id, body); } @Delete("me/saved-searches/:id") deleteSavedSearch(@Req() req: Request, @Param("id") id: string) { return this.users.deleteSavedSearch(requireUser(req), id); } }