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);
}
}