import { Controller } from "@tsed/di"; import { Get, Post, Put, Patch, Delete, Tags, Summary, Description, Returns, Security } from "@tsed/schema"; import { BodyParams, PathParams, QueryParams } from "@tsed/platform-params"; import { Req } from "@tsed/platform-http"; import { BadRequest, Unauthorized, NotFound } from "@tsed/exceptions"; import jwt from "jsonwebtoken"; import { AdminService } from "../../services/AdminService.js"; import { UserService } from "../../services/UserService.js"; const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key"; @Controller("/admin") @Tags("Admin") @Security("bearerAuth") export class AdminController { private adminService = new AdminService(); private userService = new UserService(); // Middleware to check if user is admin private async checkAdmin(req: any) { const token = req.headers.authorization?.replace("Bearer ", ""); if (!token) { throw new Unauthorized("No token provided"); } try { const decoded = jwt.verify(token, JWT_SECRET) as any; const user = await this.userService.getUserById(decoded.userId); if (!user) { throw new Unauthorized("User not found"); } if (user.role !== 'admin') { throw new Unauthorized("Admin access required"); } return user; } catch (error) { throw new Unauthorized("Invalid token or insufficient permissions"); } } // System Statistics @Get("/statistics") @Summary("Get system statistics") @Description("High-level metrics: users, jobs, interviews, tokens, revenue") @(Returns(200).Description("Statistics returned")) @(Returns(401).Description("Unauthorized")) async getSystemStatistics(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getSystemStatistics(); } // User Management @Get("/users") @Summary("List all users") @(Returns(200).Description("Users returned")) async getAllUsers(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getAllUsers(); } @Get("/users/:id") @Summary("Get a user by ID") @(Returns(200).Description("User returned")) @(Returns(404).Description("User not found")) async getUserById(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.getUserById(id); } @Put("/users/:id") @Summary("Update a user") @(Returns(200).Description("User updated")) async updateUser( @Req() req: any, @PathParams("id") id: string, @BodyParams() userData: any ) { await this.checkAdmin(req); return await this.adminService.updateUser(id, userData); } @Patch("/users/:id/toggle-status") @Summary("Toggle user active status") @(Returns(200).Description("User status toggled")) async toggleUserStatus(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.toggleUserStatus(id); } @Patch("/users/:id/password") @Summary("Change user password") @(Returns(200).Description("Password updated")) async changeUserPassword( @Req() req: any, @PathParams("id") id: string, @BodyParams() body: { new_password: string } ) { await this.checkAdmin(req); return await this.adminService.changeUserPassword(id, body.new_password); } @Post("/users") @Summary("Create a user") @(Returns(200).Description("User created")) async createUser(@Req() req: any, @BodyParams() userData: any) { await this.checkAdmin(req); return await this.adminService.createUser(userData); } // Job Management @Get("/jobs") @Summary("List all jobs") @(Returns(200).Description("Jobs returned")) async getAllJobs(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getAllJobs(); } @Get("/jobs/:id") @Summary("Get job by ID") @(Returns(200).Description("Job returned")) async getJobById(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.getJobById(id); } @Patch("/jobs/:id/status") @Summary("Update job status") @(Returns(200).Description("Job status updated")) async updateJobStatus( @Req() req: any, @PathParams("id") id: string, @BodyParams() body: { status: string } ) { await this.checkAdmin(req); return await this.adminService.updateJobStatus(id, body.status); } @Put("/jobs/:id") @Summary("Update job details") @(Returns(200).Description("Job updated")) async updateJob( @Req() req: any, @PathParams("id") id: string, @BodyParams() jobData: any ) { await this.checkAdmin(req); return await this.adminService.updateJob(id, jobData); } // Token Management @Get("/user-token-summaries") @Summary("List user token summaries") @(Returns(200).Description("Summaries returned")) async getUserTokenSummaries(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getUserTokenSummaries(); } @Post("/add-tokens") @Summary("Add tokens to a user") @(Returns(200).Description("Tokens added")) async addTokensToUser(@Req() req: any, @BodyParams() tokenData: any) { await this.checkAdmin(req); return await this.adminService.addTokensToUser(tokenData); } @Get("/token-packages") @Summary("List token packages") @(Returns(200).Description("Packages returned")) async getTokenPackages(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getTokenPackages(); } @Post("/token-packages") @Summary("Create token package") @(Returns(200).Description("Package created")) async createTokenPackage(@Req() req: any, @BodyParams() packageData: any) { await this.checkAdmin(req); return await this.adminService.createTokenPackage(packageData); } @Put("/token-packages/:id") @Summary("Update token package") @(Returns(200).Description("Package updated")) async updateTokenPackage( @Req() req: any, @PathParams("id") id: string, @BodyParams() packageData: any ) { await this.checkAdmin(req); return await this.adminService.updateTokenPackage(id, packageData); } @Patch("/token-packages/:id/toggle-status") @Summary("Toggle token package active status") @(Returns(200).Description("Package status toggled")) async toggleTokenPackageStatus(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.toggleTokenPackageStatus(id); } @Delete("/token-packages/:id") @Summary("Delete token package") @(Returns(200).Description("Package deleted")) async deleteTokenPackage(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.deleteTokenPackage(id); } // Interview Management @Get("/interviews") @Summary("List interviews") @(Returns(200).Description("Interviews returned")) async getAllInterviews(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getAllInterviews(); } @Get("/interviews/:id") @Summary("Get interview by ID") @(Returns(200).Description("Interview returned")) async getInterviewById(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.getInterviewById(id); } // Payment Records @Get("/payments") @Summary("List payment records") @(Returns(200).Description("Payments returned")) async getPaymentRecords(@Req() req: any) { await this.checkAdmin(req); return await this.adminService.getPaymentRecords(); } @Get("/payments/:id") @Summary("Get payment by ID") @(Returns(200).Description("Payment returned")) async getPaymentById(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.getPaymentById(id); } // Job Links Management @Get("/jobs/:id/links") @Summary("Get job links") @(Returns(200).Description("Job links returned")) async getJobLinks(@Req() req: any, @PathParams("id") id: string) { await this.checkAdmin(req); return await this.adminService.getJobLinks(id); } @Post("/jobs/:id/create-link") @Summary("Create job link for testing") @(Returns(200).Description("Job link created")) async createJobLink(@Req() req: any, @PathParams("id") id: string, @BodyParams() linkData: any) { await this.checkAdmin(req); return await this.adminService.createJobLink(id, linkData.tokensAvailable || 1); } }