import { Controller, Get, Post, Body, Param, Query, Put, Delete, HttpCode, UseGuards, Req, ForbiddenException, } from "@nestjs/common"; import { UsersService } from "./users.service"; import { ApiTags, ApiOperation, ApiBearerAuth } from "@nestjs/swagger"; import { JwtAuthGuard } from "../auth/jwt-auth.guard"; import { RolesGuard } from "../auth/roles.guard"; import { Roles } from "../auth/roles.decorator"; import { RegisterDto } from "./dto/register.dto"; import { LoginDto } from "./dto/login.dto"; import { GoogleLoginDto } from "./dto/google-login.dto"; import { SupabaseLoginDto } from "./dto/supabase-login.dto"; import { UpdateUserDto } from "./dto/update-user.dto"; import { CreateFeedbackDto } from "./dto/create-feedback.dto"; @ApiTags("Authentication & User Management") @Controller() export class UsersController { constructor(private usersService: UsersService) {} @Post("auth/register") @ApiOperation({ summary: "Register a new student account" }) async register(@Body() dto: RegisterDto) { return this.usersService.register(dto.email, dto.name, dto.password); } @Post("auth/login") @HttpCode(200) @ApiOperation({ summary: "Login student account" }) async login(@Body() dto: LoginDto) { return this.usersService.login(dto.email, dto.password); } @Post("auth/google") @HttpCode(200) @ApiOperation({ summary: "Authenticate with Google ID Token" }) async googleLogin(@Body() dto: GoogleLoginDto) { return this.usersService.googleLogin(dto.idToken); } @Post("auth/supabase") @HttpCode(200) @ApiOperation({ summary: "Authenticate with Supabase JWT Token" }) async supabaseLogin(@Body() dto: SupabaseLoginDto) { return this.usersService.supabaseLogin(dto.token); } @Get("users") @UseGuards(JwtAuthGuard, RolesGuard) @Roles("admin") @ApiBearerAuth() @ApiOperation({ summary: "List all users (Admin)" }) async getUsers(@Query("take") take?: string, @Query("skip") skip?: string) { const limit = take ? parseInt(take, 10) : 50; const offset = skip ? parseInt(skip, 10) : 0; return this.usersService.findAll(limit, offset); } @Get("users/:id") @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: "Get details of a single user" }) async getUserById(@Param("id") id: string, @Req() req: any) { if (req.user.role !== "admin" && req.user.id !== id) { throw new ForbiddenException("You can only access your own user profile"); } return this.usersService.findById(id); } @Put("users/:id") @UseGuards(JwtAuthGuard, RolesGuard) @Roles("admin") @ApiBearerAuth() @ApiOperation({ summary: "Update a user (Admin)" }) async updateUser(@Param("id") id: string, @Body() dto: UpdateUserDto) { return this.usersService.update(id, dto.name, dto.email, dto.streak); } @Delete("users/:id") @UseGuards(JwtAuthGuard, RolesGuard) @Roles("admin") @ApiBearerAuth() @ApiOperation({ summary: "Delete a user (Admin)" }) async deleteUser(@Param("id") id: string) { return this.usersService.remove(id); } @Post("feedbacks") @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: "Submit feedback (Student)" }) async createFeedback(@Body() dto: CreateFeedbackDto, @Req() req: any) { return this.usersService.createFeedback(req.user.id, dto.content); } @Get("feedbacks") @UseGuards(JwtAuthGuard, RolesGuard) @Roles("admin") @ApiBearerAuth() @ApiOperation({ summary: "List all feedbacks (Admin)" }) async getFeedbacks() { return this.usersService.findAllFeedbacks(); } }