Adjust
Operasi increment dan decrement atomik pada field numerik
Endpoint /adjust melakukan perubahan nilai numerik secara relatif (increment atau decrement) menggunakan operasi atomik di level SQL. Berbeda dengan /update yang mengganti nilai secara absolut, /adjust menambah atau mengurangi nilai yang sudah ada sehingga aman dari race condition saat concurrent request.
Kapan Menggunakan /adjust (When to Use /adjust)
| Skenario | Contoh | Mengapa Bukan /update |
|---|---|---|
| Stock masuk (inbound) | Stok item bertambah 25 unit | /update rentan race condition jika dua request membaca nilai yang sama |
| Stock keluar (outbound) | Stok item berkurang 10 unit | /adjust menggunakan SET stock = stock - 10 yang bersifat atomik |
| Penyesuaian saldo | Saldo customer bertambah 500.000 | Operasi relatif lebih akurat dari baca-modifikasi-tulis |
| Koreksi kuantitas | Koreksi stok setelah stock opname | Guard clause mencegah stok menjadi negatif |
Perbedaan /adjust vs /update (Comparison)
| Aspek | /update | /adjust |
|---|---|---|
| Operasi SQL | SET stock = 90 (nilai absolut) | SET stock = stock + (-10) (nilai relatif) |
| Race condition | Rentan. Dua request bisa membaca stock = 100, keduanya menulis 90 | Aman. Redis lock + atomic SQL menjamin konsistensi (consistency) |
| Guard clause | Tidak ada | Ada. Mencegah nilai turun di bawah minimum |
| Use case | Edit data form (mengubah nama, alamat) | Operasi numerik (stok, saldo, kuantitas) |
Konfigurasi Payload (Payload Configuration)
Endpoint /adjust memerlukan adjust: true di action dan konfigurasi adjustConfig:
{
"tableName": "item_product",
"primaryKey": "item_product_id",
"action": {
"adjust": true
},
"adjustConfig": {
"fields": {
"stock": {
"type": "number",
"min": 0,
"allowNegativeResult": false
}
},
"reasonRequired": false
}
}| Property | Tipe | Keterangan |
|---|---|---|
fields.{name}.type | string | Tipe field ("number") |
fields.{name}.min | number | Nilai minimum setelah adjustment |
fields.{name}.allowNegativeResult | boolean | Jika false, guard clause mencegah nilai negatif |
reasonRequired | boolean | Jika true, field reason wajib dikirim di request |
Cara Penggunaan (How to Use)
Mengurangi Stok (Decrement)
{
"item_product_id": "04d71c62-5736-5337-ba8f-98d353067d1b",
"adjustments": [
{ "field": "stock", "value": -10 }
],
"reason": "Stock outbound #OUT-001"
}valuepositif = increment (tambah)valuenegatif = decrement (kurangi)
Response (200 OK):
{
"success": true,
"message": "item-product data successfully adjusted",
"data": {
"item_product_id": "04d71c62-...",
"stock": 90
},
"timestamp": "2026-04-16T10:30:00.000Z"
}Menambah Stok (Increment)
{
"item_product_id": "04d71c62-5736-5337-ba8f-98d353067d1b",
"adjustments": [
{ "field": "stock", "value": 25 }
],
"reason": "Stock inbound #INB-001"
}Adjustment Multi-Field
Beberapa field dapat di-adjust dalam satu request:
{
"item_product_id": "04d71c62-5736-5337-ba8f-98d353067d1b",
"adjustments": [
{ "field": "stock", "value": -5 },
{ "field": "reserved_qty", "value": 5 }
]
}Guard Clause
Jika allowNegativeResult: false (atau min di-set), RESTForge menambahkan guard clause di SQL WHERE:
UPDATE item_product
SET stock = stock + (-10)
WHERE item_product_id = $1
AND (stock + (-10)) >= 0 -- guard clauseJika guard clause tidak terpenuhi (misalnya stok saat ini 5 dan dicoba dikurangi 10), operasi gagal dengan HTTP 409:
{
"success": false,
"error": "Constraint violation",
"message": "Adjustment would result in value below minimum for field: stock",
"timestamp": "2026-04-16T10:30:00.000Z"
}Guard clause dievaluasi di level SQL sehingga bersifat atomik. Tidak ada jeda antara pengecekan dan update yang bisa dieksploitasi oleh concurrent request.
Error Umum (Common Errors)
| Situasi | HTTP Code | Keterangan |
|---|---|---|
| Primary key tidak dikirim | 400 | Field PK wajib ada |
Array adjustments kosong | 400 | Minimal satu adjustment diperlukan |
| Field tidak dikonfigurasi | 400 | Field yang di-adjust harus terdaftar di adjustConfig.fields |
| Record tidak ditemukan | 404 | Tidak ada record dengan primary key tersebut |
| Guard clause gagal | 409 | Adjustment menyebabkan nilai di bawah minimum |
Langkah Selanjutnya (Next Steps)
- Aggregate untuk fungsi agregasi data
- CRUD Dasar untuk operasi create, update, dan delete
- POST /adjust untuk spesifikasi teknis lengkap