250 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			250 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | 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); | ||
|  |   } | ||
|  | } |