Job Grade API - Dokumentasi Teknis
Overview
Dokumentasi teknis untuk developer yang akan maintain atau develop lebih lanjut pada Job Grade API module.
Arsitektur
Job Grade module menggunakan pola Command & Query:
job-grade/
├── commands/
│ ├── create.cmd.ts
│ ├── update.cmd.ts
│ └── soft-delete.cmd.ts
├── queries/
│ ├── get.query.ts
│ └── get-by-id.query.ts
├── dto/
├── helper/ # generateSlug, mapToDetailResponse
├── validation/
├── job-grade.controller.ts
├── job-grade.service.ts
├── job-grade.module.ts
└── docs/
Tech Stack
- Framework: NestJS
- Database: PostgreSQL dengan Prisma ORM
- Validation: class-validator, class-transformer
- Auth: AuthGuard (JWT), tenant dari current user
- RLS: createTenantClient
Database Schema
Table: job_grades
| Column | Type | Keterangan |
|---|---|---|
| id | UUID | PK |
| tenant_id | UUID | NOT NULL |
| key | VARCHAR(50) | UNIQUE, slug dari name |
| name | VARCHAR(100) | NOT NULL |
| description | VARCHAR(255) | NULL |
| level_id | UUID | NOT NULL, FK → job_levels |
| is_active | BOOLEAN | DEFAULT true |
| created_by | UUID | NULL |
| created_by_name | VARCHAR(100) | NULL |
| created_at | TIMESTAMPTZ | DEFAULT now() |
| updated_by | UUID | NULL |
| updated_by_name | VARCHAR(100) | NULL |
| updated_at | TIMESTAMPTZ | @updatedAt |
| deleted_by | UUID | NULL |
| deleted_by_name | VARCHAR(100) | NULL |
| deleted_at | TIMESTAMPTZ | NULL |
Relasi:
JobGrade.level_id→JobLevel.idJobTitle.grade_id→JobGrade.id
Module Structure
1. Commands
CreateJobGradeCommand
- File:
commands/create.cmd.ts - Alur:
- createTenantClient(tenantId)
- key = JobGradeValidation.checkSlugUnique(client, JobGradeHelper.generateSlug(dto.name))
JobLevelValidation.validateNotFound(client, { id: dto.level_id })- Transaction:
jobGrade.create({ tenantId, key, name, levelId, description, isActive: true }) - mapToDetailResponse(result)
UpdateJobGradeCommand
- File:
commands/update.cmd.ts - Alur: validateNotFound job grade → validateNotFound job level → key = checkSlugUnique → update
SoftDeleteJobGradeCommand
- File:
commands/soft-delete.cmd.ts
2. Validation
JobGradeValidation
- validateExistence(client, where) — Throw 400
job-grade.is_existjika record ada - validateNotFound(client, where) — Throw 404
job-grade.is_not_foundjika record tidak ada - checkSlugUnique(client, slug, attempt) — Return slug unik (tambah suffix -1, -2 jika bentrok)
3. Helper
- generateSlug(str) — Lowercase, trim, non-alphanumeric →
- - mapToDetailResponse(jg) — Map ke response DTO
Controller Endpoints
- Base route:
job-grades - POST
/— create - GET
/— findAll - GET
/:id— findOne - PATCH
/:id— update - DELETE
/:id— softDelete
Error Codes
job-grade.is_not_found— Record tidak ditemukanjob-grade.is_exist— Record sudah adajob-level.is_not_found— level_id tidak valid