Hệ thống Quản lý Nhân sự (HRMS) là một ứng dụng toàn diện giúp doanh nghiệp quản lý hiệu quả các quy trình nhân sự, bao gồm: quản lý thông tin nhân viên, phòng ban, chấm công, nghỉ phép, bảng lương, báo cáo thống kê, và nhiều tính năng khác.
- Node.js (v16 trở lên)
- PostgreSQL (v14 trở lên)
- pgAdmin (tùy chọn, để quản lý cơ sở dữ liệu)
- Tải và cài đặt PostgreSQL từ trang chủ PostgreSQL
- Sau khi cài đặt, mở pgAdmin
- Vào pgAdmin > server > Postgres 17 > chuột phải chọn Register > server
- Nhập tên server và thông tin kết nối
- Sao chép file
env.examplethành file.env - Cập nhật các thông tin kết nối database trong file
.env:
DATABASE_TYPE=postgres
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USERNAME=<tên_đăng_nhập>
DATABASE_PASSWORD=<mật_khẩu>
DATABASE_NAME=<tên_database>
DATABASE_SYNCHRONIZE=true
# Cài đặt các gói phụ thuộc
npm install
# Khởi động ứng dụng ở chế độ phát triển
npm run start:dev- API endpoint: http://localhost:3005/api
- Tài liệu Swagger: http://localhost:3005/docs
MCP Server giúp bạn truy vấn cơ sở dữ liệu một cách dễ dàng thông qua Cursor.
- Vào Settings > MCP > thêm mới cấu hình sau:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://<username>:<password>@localhost:5432/<tên_db>"
]
}
}
}- Thay thế
<username>,<password>, và<tên_db>với thông tin cấu hình trong file.env - Khi cấu hình thành công, biểu tượng MCP sẽ chuyển sang màu xanh
- Để kiểm tra kết nối, bạn có thể chat với Cursor: "dùng MCP tool /query để kiểm tra kết nối cơ sở dữ liệu"
Hệ thống HRMS sử dụng Swagger để tạo tài liệu API tự động. Dưới đây là hướng dẫn để tùy chỉnh và làm phong phú tài liệu API.
Cấu hình Swagger được đặt trong file src/main.ts. Có thể tùy chỉnh các thông số sau:
// Cấu hình Swagger
const config = new DocumentBuilder()
.setTitle('Hệ thống Quản lý Nhân sự (HRMS)')
.setDescription('API Documentation cho hệ thống quản lý nhân sự toàn diện')
.setVersion('1.0')
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
in: 'header',
},
'JWT',
)
.addTag('auth', 'Xác thực và phân quyền người dùng')
.addTag('users', 'Quản lý thông tin người dùng và nhân viên')
.addTag('departments', 'Quản lý phòng ban và cơ cấu tổ chức')
.addTag('attendance', 'Quản lý chấm công và ca làm việc')
.addTag('leave', 'Quản lý nghỉ phép và đơn từ')
.addTag('payroll', 'Quản lý lương và thanh toán')
.addTag('reports', 'Báo cáo và thống kê')
.addTag('documents', 'Quản lý tài liệu và lưu trữ')
.addTag('tasks', 'Quản lý công việc và dự án')
.build();
// Tùy chỉnh giao diện Swagger UI
SwaggerModule.setup('docs', app, document, {
swaggerOptions: {
persistAuthorization: true,
tagsSorter: 'alpha',
operationsSorter: 'alpha',
docExpansion: 'none',
defaultModelsExpandDepth: 1,
defaultModelExpandDepth: 1,
filter: true,
},
customSiteTitle: 'HRMS API Documentation',
customCss: '.swagger-ui .topbar { display: none }',
});Sử dụng các decorator của @nestjs/swagger để mô tả các API endpoints:
@ApiTags('auth')
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post('login')
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: 'Đăng nhập hệ thống',
description: 'API đăng nhập, trả về access token và refresh token khi xác thực thành công'
})
@ApiResponse({
status: 200,
description: 'Đăng nhập thành công',
schema: {
type: 'object',
properties: {
accessToken: {
type: 'string',
example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
},
refreshToken: {
type: 'string',
example: 'a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6'
}
}
}
})
@ApiResponse({ status: 401, description: 'Thông tin đăng nhập không chính xác' })
async login(@Body() loginDto: LoginDto): Promise<TokensResponse> {
return this.authService.login(loginDto.email, loginDto.password);
}
}Sử dụng ApiProperty để mô tả chi tiết về các trường dữ liệu:
export class CreateUserDto {
@ApiProperty({
description: 'Địa chỉ email người dùng (dùng để đăng nhập)',
example: 'nguyen.van.a@company.com',
required: true
})
@IsEmail()
email: string;
@ApiProperty({
description: 'Mật khẩu (tối thiểu 8 ký tự, bao gồm chữ hoa, chữ thường và số)',
example: 'Password123',
minLength: 8,
required: true
})
@IsStrongPassword()
password: string;
@ApiProperty({
description: 'Họ của nhân viên',
example: 'Nguyễn',
required: true
})
@IsString()
firstName: string;
@ApiProperty({
description: 'Tên của nhân viên',
example: 'Văn A',
required: true
})
@IsString()
lastName: string;
@ApiProperty({
description: 'Phòng ban của nhân viên',
example: '123e4567-e89b-12d3-a456-426614174000',
required: false
})
@IsUUID()
@IsOptional()
departmentId?: string;
@ApiProperty({
description: 'Vai trò của người dùng trong hệ thống',
enum: Role,
example: Role.USER,
default: Role.USER
})
@IsEnum(Role)
@IsOptional()
role?: Role;
}Thêm ví dụ cho Request Body:
@Post('departments')
@Roles(Role.ADMIN, Role.HR)
@ApiOperation({
summary: 'Tạo phòng ban mới',
description: 'Tạo phòng ban mới trong hệ thống. Yêu cầu quyền Admin hoặc HR.'
})
@ApiBody({
description: 'Thông tin phòng ban cần tạo',
type: CreateDepartmentDto,
examples: {
example1: {
summary: 'Phòng ban cấp cao',
description: 'Tạo phòng ban cấp cao với phòng ban cha',
value: {
name: 'Phòng Kỹ thuật',
description: 'Phòng kỹ thuật phụ trách các vấn đề kỹ thuật của công ty',
parentDepartmentId: '123e4567-e89b-12d3-a456-426614174000'
}
},
example2: {
summary: 'Phòng ban gốc',
description: 'Tạo phòng ban gốc không có phòng ban cha',
value: {
name: 'Ban Giám đốc',
description: 'Ban điều hành cấp cao của công ty'
}
}
}
})
@ApiResponse({
status: 201,
description: 'Phòng ban đã được tạo thành công',
type: DepartmentResponseDto
})
@ApiResponse({ status: 400, description: 'Dữ liệu không hợp lệ' })
@ApiResponse({ status: 401, description: 'Chưa xác thực' })
@ApiResponse({ status: 403, description: 'Không có quyền truy cập' })
createDepartment(@Body() createDepartmentDto: CreateDepartmentDto) {
return this.departmentService.create(createDepartmentDto);
}Dưới đây là một số mẫu dữ liệu để test các API chính trong hệ thống:
{
"email": "nguyen.van.a@company.com",
"password": "Password123",
"firstName": "Nguyễn",
"lastName": "Văn A",
"phone": "0901234567"
}{
"email": "nguyen.van.a@company.com",
"password": "Password123"
}{
"name": "Phòng Nhân sự",
"description": "Phòng quản lý nhân sự và tuyển dụng",
"code": "HR",
"parentId": null
}{
"name": "Ca sáng",
"startTime": "08:00",
"endTime": "12:00",
"description": "Ca làm việc buổi sáng",
"isDefault": true
}{
"employeeId": "123e4567-e89b-12d3-a456-426614174000",
"leaveTypeId": "123e4567-e89b-12d3-a456-426614174001",
"startDate": "2023-11-20",
"endDate": "2023-11-22",
"reason": "Nghỉ phép đi du lịch với gia đình",
"contactInfo": "0901234567"
}{
"employeeId": "123e4567-e89b-12d3-a456-426614174000",
"basicSalary": 10000000,
"effectiveDate": "2023-01-01",
"currency": "VND",
"paymentMethod": "BANK_TRANSFER",
"bankAccount": "0123456789",
"bankName": "VCB"
}Để test hệ thống một cách hiệu quả, hãy làm theo thứ tự sau:
- Đăng ký tài khoản:
POST /api/auth/register - Đăng nhập:
POST /api/auth/login(Lưu access token để sử dụng cho các API khác)
- Tạo phòng ban:
POST /api/v1/departments - Xem danh sách phòng ban:
GET /api/v1/departments
- Tạo người dùng mới:
POST /api/v1/admin/users - Thêm nhân viên vào phòng ban:
PATCH /api/v1/admin/users/:id
- Tạo ca làm việc:
POST /api/shifts - Phân công ca làm việc:
POST /api/shifts/assign - Chấm công:
POST /api/attendance/check-invàPOST /api/attendance/check-out
- Tạo chính sách nghỉ phép:
POST /api/leave-policies - Cập nhật số ngày nghỉ phép cho nhân viên:
POST /api/leave-balances - Tạo đơn xin nghỉ phép:
POST /api/leave-requests - Phê duyệt đơn nghỉ phép:
PATCH /api/leave-requests/:id/approve
- Cài đặt lương cơ bản:
POST /api/payroll/salaries - Thiết lập các khoản phụ cấp:
POST /api/payroll/allowances - Thiết lập các khoản khấu trừ:
POST /api/payroll/deductions - Cấu hình thuế:
POST /api/payroll/tax-configs - Tạo và phê duyệt phiếu lương:
POST /api/payroll/payslipsvàPATCH /api/payroll/payslips/:id/approve
- Tạo danh mục tài liệu:
POST /api/document-categories - Tải lên tài liệu:
POST /api/documents - Chia sẻ tài liệu:
POST /api/document-shares/:documentId
- Tạo dự án:
POST /api/projects - Tạo trạng thái task:
POST /api/task-statuses - Tạo task:
POST /api/tasks - Cập nhật tiến độ task:
PUT /api/tasks/:id/status
- Xem báo cáo hiệu suất:
GET /api/v1/reports/performance - Xem báo cáo nhân sự:
GET /api/v1/reports/hr - Xem báo cáo chấm công:
GET /api/v1/reports/attendance - Xuất báo cáo:
POST /api/v1/reports/export
- Đảm bảo tuân theo thứ tự logic: tạo phòng ban trước khi thêm nhân viên, tạo ca làm việc trước khi chấm công, v.v.
- Sử dụng Swagger UI (http://localhost:3005/docs) để dễ dàng thử nghiệm các API
- Token xác thực: Đặt token nhận được sau khi đăng nhập vào header "Authorization" với giá trị "Bearer " khi gọi các API yêu cầu xác thực
- Nếu gặp lỗi khi gọi API, kiểm tra console log của server để biết thêm chi tiết