UNPKG

@diagramers/api

Version:

Diagramers API - A comprehensive Node.js API template with TypeScript, Firebase Functions, and Socket.io

375 lines (366 loc) 11.1 kB
import { Request, Response } from 'express'; import { Result } from '../../../shared/types/result'; import { ResponseCode } from '../../../shared/constants/enums'; import { handleResponse } from '../../../shared/utils/handle-response'; import { UserService } from '../services/user.service'; import { IUserCreate, IUserUpdate } from '../entities/user.entity'; export class UserController { private userService: UserService; constructor() { this.userService = new UserService(); } /** * @openapi * /api/users: * get: * summary: Get all users * description: Retrieve a list of all active users * tags: [Users] * responses: * 200: * description: List of users retrieved successfully * content: * application/json: * schema: * type: object * properties: * Data: * type: array * items: * $ref: '#/components/schemas/User' * StatusCode: * type: integer * example: 1000 * 400: * description: Bad request */ async getAll(req: Request, res: Response): Promise<void> { try { const result = await this.userService.getAll(); handleResponse(res, result); } catch (error: any) { handleResponse(res, Result.error('Failed to fetch users', error.message)); } } /** * @openapi * /api/users/{id}: * get: * summary: Get user by ID * description: Retrieve a specific user by their ID * tags: [Users] * parameters: * - in: path * name: id * required: true * schema: * type: string * description: User ID * responses: * 200: * description: User retrieved successfully * content: * application/json: * schema: * type: object * properties: * Data: * $ref: '#/components/schemas/User' * StatusCode: * type: integer * example: 1000 * 404: * description: User not found */ async getById(req: Request, res: Response): Promise<void> { try { const { id } = req.params; const result = await this.userService.getById(id); handleResponse(res, result); } catch (error: any) { handleResponse(res, Result.error('Failed to fetch user', error.message)); } } /** * @openapi * /api/users: * post: * summary: Create new user * description: Create a new user account * tags: [Users] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - email * - username * - password * properties: * email: * type: string * format: email * username: * type: string * minLength: 3 * password: * type: string * minLength: 6 * firstName: * type: string * lastName: * type: string * phone: * type: string * role: * type: string * enum: [user, admin, moderator] * responses: * 201: * description: User created successfully * content: * application/json: * schema: * type: object * properties: * Data: * $ref: '#/components/schemas/User' * StatusCode: * type: integer * example: 1000 * 409: * description: User already exists * 400: * description: Bad request or missing required fields */ async create(req: Request, res: Response): Promise<void> { try { const userData: IUserCreate = req.body; // Basic validation if (!userData.email || !userData.username || !userData.password) { handleResponse(res, Result.missingFields('Email, username, and password are required')); return; } const result = await this.userService.create(userData); handleResponse(res, result); } catch (error: any) { handleResponse(res, Result.error('Failed to create user', error.message)); } } /** * @openapi * /api/users/{id}: * put: * summary: Update user * description: Update an existing user's information * tags: [Users] * parameters: * - in: path * name: id * required: true * schema: * type: string * description: User ID * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * firstName: * type: string * lastName: * type: string * phone: * type: string * avatar: * type: string * isActive: * type: boolean * role: * type: string * enum: [user, admin, moderator] * responses: * 200: * description: User updated successfully * content: * application/json: * schema: * type: object * properties: * Data: * $ref: '#/components/schemas/User' * StatusCode: * type: integer * example: 1000 * 404: * description: User not found */ async update(req: Request, res: Response): Promise<void> { try { const { id } = req.params; const userData: IUserUpdate = req.body; const result = await this.userService.update(id, userData); handleResponse(res, result); } catch (error: any) { handleResponse(res, Result.error('Failed to update user', error.message)); } } /** * @openapi * /api/users/{id}: * delete: * summary: Delete user * description: Soft delete a user (sets status to 0) * tags: [Users] * parameters: * - in: path * name: id * required: true * schema: * type: string * description: User ID * responses: * 200: * description: User deleted successfully * content: * application/json: * schema: * type: object * properties: * Data: * type: boolean * example: true * StatusCode: * type: integer * example: 1000 * 404: * description: User not found */ async delete(req: Request, res: Response): Promise<void> { try { const { id } = req.params; const result = await this.userService.delete(id); handleResponse(res, result); } catch (error: any) { handleResponse(res, Result.error('Failed to delete user', error.message)); } } /** * @openapi * /api/users/profile: * get: * summary: Get user profile * description: Get the current authenticated user's profile * tags: [Users] * security: * - bearerAuth: [] * responses: * 200: * description: User profile retrieved successfully * content: * application/json: * schema: * type: object * properties: * Data: * $ref: '#/components/schemas/User' * StatusCode: * type: integer * example: 1000 * 401: * description: User not authenticated * 404: * description: User not found */ async getProfile(req: Request, res: Response): Promise<void> { try { // Assuming user ID is available from auth middleware const userId = (req as any).user?.id; if (!userId) { handleResponse(res, Result.unauthorized('User not authenticated')); return; } const result = await this.userService.getById(userId); handleResponse(res, result); } catch (error: any) { handleResponse(res, Result.error('Failed to fetch profile', error.message)); } } } /** * @openapi * components: * schemas: * User: * type: object * properties: * _id: * type: string * description: User ID * email: * type: string * format: email * description: User email address * username: * type: string * description: Username * firstName: * type: string * description: First name * lastName: * type: string * description: Last name * phone: * type: string * description: Phone number * avatar: * type: string * description: Avatar URL * isActive: * type: boolean * description: Whether user is active * lastLoginAt: * type: string * format: date-time * description: Last login timestamp * emailVerified: * type: boolean * description: Whether email is verified * phoneVerified: * type: boolean * description: Whether phone is verified * role: * type: string * enum: [user, admin, moderator] * description: User role * permissions: * type: array * items: * type: string * description: User permissions * status: * type: integer * description: User status (1 - active, 0 - deleted, -1 - suspended) * createdAt: * type: string * format: date-time * description: Creation timestamp * updatedAt: * type: string * format: date-time * description: Last update timestamp * required: * - email * - username * - isActive * - emailVerified * - phoneVerified * - role * - status * - createdAt * - updatedAt */