135dika / handover_verification_checklist.md

Last active 1 month ago

Like 0
handover_verification_checklist.md Raw

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 verificationChecks dihapus (itu penyebab load seluruh row per kategori).
  • Kalau UI butuh daftar check per kategori, ambil via endpoint check yang ada.
  • verifiedCounter sebelumnya 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 (internal groupBy, 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 .env setiap 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 dev perlu dijalankan (index baru + kolom panjang @db.Text). Belum ada migration.
  • Auth/JWT: sengaja belum diimplementasi (keputusan owner). Semua endpoint masih publik.