Handover Backend → Frontend
Perubahan perilaku API hasil audit backend. Semua contoh payload di bawah diambil dari kode aktual (src/features/...), bukan desain baru.
Identifikasi endpoint memakai controller + method. Path lengkap mengikuti route yang sudah ada di frontend (tidak ada route path yang berubah).
1. Pagination — HANYA endpoint list WEB
1a. Web verification-checks — GET / (findAll)
Request (query params, baru):
| param | tipe | default | aturan |
|---|---|---|---|
take |
number | 50 |
di-clamp ke 1..100 (angka di luar → dibatasi, bukan error) |
skip |
number | 0 |
di-clamp ≥ 0 |
GET /?take=20&skip=40
Response: bentuk array check tidak berubah. Yang berubah: maksimal take row per request (sebelumnya seluruh isi tabel).
1b. Web verification-checks — POST /find (findManyByOwnerId)
Request:
// body (tidak berubah)
{ "ownerId": "..." }
// query params baru: status (lihat §2), take, skip — aturan clamp sama dengan §1a
POST /find?status=rejected&take=20&skip=0
Response: bentuk tidak berubah, dibatasi take.
1c. Mobile verification-checks — list (findManyByOwnerId)
⚠️ Tidak ada pagination di endpoint mobile (ownerId via body, status via query). Default masih "semua row". Jangan kirim take/skip ke sini — diabaikan.
2. Filter status — perilaku diperbaiki
Sebelum (bug): semua nilai selain verified dianggap "tanpa filter" → status=rejected dan status=need_approval menampilkan semua row.
Sesudah (web + mobile, mapping sama):
query status |
hasil filter |
|---|---|
verified atau approved |
hanya APPROVED |
rejected |
hanya REJECTED |
need_approval atau need-approval |
hanya NEED_APPROVAL |
| tidak dikirim / nilai tidak dikenal | tanpa filter (semua row) — ini default lama |
Tidak ada perubahan shape request/response. Klien yang tadinya "sengaja" pakai nilai aneh untuk melihat semua data: perilaku itu tetap berfungsi (nilai tidak dikenal → semua).
3. Web category list — ⚠️ SHAPE RESPONSE BERUBAH
GET category list web (findAll(projectId, ownerId) di VerificationCheckCategoriesWebService).
Sebelum:
[
{
"id": "...", "name": "...", "ownerId": "...", "projectId": "...",
"verificationChecks": [ /* array penuh semua check di kategori ini */ ]
}
]
Sesudah:
[
{
"id": "...",
"name": "...",
"ownerId": "...",
"projectId": "...",
"verifiedCounter": 3 // jumlah check berstatus APPROVED di kategori ini
}
]
- Nested
verificationChecksdihapus (itu penyebab load seluruh row per kategori). - Kalau UI butuh daftar check per kategori, ambil via endpoint check yang ada.
verifiedCountersebelumnya juga ada? Tidak — ini pengganti data yang sebelumnya dihitung klien dari nested array.
Endpoint web category lain tidak berubah shape:
- status per project (
findAllStatuses): tetap[{ "projectId": "...", "verified": "VERIFIED" | "UNVERIFIED" | "REJECTED" }]— hanya lebih cepat (internalgroupBy, presedens: REJECTED > UNVERIFIED > VERIFIED). - detail (
findOne): tetap category +verificationChecks+attachments, epoch seconds.
4. Mobile category findOne — sekarang berfungsi
Sebelum (bug): id tidak pernah terbaca dari route → query selalu miss → endpoint error/404 untuk semua id.
Sesudah: @Param('id') benar → return kategori sesuai id seperti endpoint lain.
- Klien yang punya workaround (mis. pakai endpoint lain untuk detail kategori mobile) boleh dihapus.
- Klien yang pernah mengandalkan error-nya: tidak ada — ini strictly perbaikan.
5. Mobile category import — response berisi
POST .../import (mobile category, multipart file).
Sebelum (bug): response body selalu [] berapapun isi Excel.
Sesudah: array kategori yang ter-create/ter-find:
[
{ "id": "...", "name": "...", "projectId": "...", "ownerId": "...", "createdAt": ..., "updatedAt": ... }
]
Import check (verification-checks processImport) juga di-batch — shape response tetap, hanya lebih cepat dan aman untuk file besar.
6. Error responses
| kasus | sebelum | sesudah |
|---|---|---|
JSON body rusak di create/update check mobile (field verificationCheck) |
500 (SyntaxError unhandled) | 400 "Invalid JSON payload" |
| record tidak ditemukan (Prisma P2025) | 404 | 404 (tidak berubah) |
| error server tak terduga | 500 + detail internal Prisma bocor (meta: query/model) |
500 body generik: "An unexpected error occurred." |
Contoh 400:
{ "statusCode": 400, "message": "Invalid JSON payload", "error": "Bad Request" }
Jangan parse message 500 untuk logika — isinya selalu generik sekarang.
7. Upload (multipart)
Berlaku di semua endpoint upload (check attachments, category import, dsb):
| batas | sebelum | sesudah |
|---|---|---|
| jumlah file per request | praktis unlimited (1000 × 40MB) | maks 10 file |
| ukuran per file | 200MB (Excel) / 40MB | 10 MB |
| ekstensi file | apa pun yang klien kirim | dipaksa dari mimetype: hanya jpg/jpeg/png/pdf (upload dokumen) |
- Upload melebihi batas → ditolak multer (HTTP 4xx), bukan dipotong.
- Nama file asli klien tidak lagi dipakai untuk ekstensi — server yang menentukan dari mimetype. Rename file di sisi klien tidak berpengaruh.
- Request JSON dibatasi 1 MB.
8. CORS — action needed per environment
origin: '*' dihapus. Sekarang dari env:
CORS_ORIGINS="https://app.example.com,https://admin.example.com"
CORS_ORIGINS="*"→ semua origin diizinkan (transisi sementara; ganti ke daftar asal begitu lengkap).- Kosong/tidak di-set → CORS mati (same-origin only) → browser frontend cross-origin akan block.
- Wajib diisi di
.envsetiap environment sebelum deploy.
9. Env baru (ops)
REDIS_URL="redis://default:password@localhost:6379" # prioritas; support username+password
#REDIS_HOST="localhost" # fallback kalau REDIS_URL kosong
#REDIS_PORT="6379"
CORS_ORIGINS="" # wajib diisi untuk akses cross-origin
Catatan backend (bukan urusan frontend)
prisma migrate devperlu dijalankan (index baru + kolom panjang@db.Text). Belum ada migration.- Auth/JWT: sengaja belum diimplementasi (keputusan owner). Semua endpoint masih publik.