POST /update-composite
Spesifikasi endpoint update-composite untuk memperbarui data master-detail
Endpoint /update-composite digunakan untuk memperbarui data header (master) beserta operasi detail item (insert, update, delete) dalam satu request atomik. Seluruh operasi dijalankan dalam satu transaksi database sehingga jika salah satu bagian gagal, seluruh operasi di-rollback.
Referensi Cepat (Quick Reference)
| Properti | Nilai |
|---|---|
| Method | POST |
| URL | /api/{project}/{endpoint}/update-composite |
| Content-Type | application/json |
| Status Sukses | 200 OK |
| Database | PostgreSQL, MySQL, Oracle |
| Transaksi | Atomik (header + detail dalam satu transaksi) |
| Cache | Invalidasi otomatis setelah update berhasil |
| Urutan Eksekusi | DELETE → UPDATE → INSERT → RECALCULATE → UPDATE HEADER → COMMIT |
Ikhtisar (Overview)
Endpoint ini dirancang untuk skenario update master-detail di mana header dan detail item perlu diperbarui secara bersamaan. Operasi header bersifat partial update, artinya hanya field yang dikirim (selain primary key) yang akan diubah. Operasi detail dikirim dalam bentuk object dengan tiga properti opsional: insert, update, dan delete.
Primary key header bersifat wajib untuk mengidentifikasi record yang akan diperbarui. Jika hanya perlu memperbarui field header tanpa menyentuh detail, cukup kirim data header saja tanpa menyertakan object detail.
Format Request (Request Format)
Diagram Struktur (Structure Diagram)
{
"{header_table}": {
{primary_key}: "existing-uuid", ← wajib
field_1: new_value, ← opsional (partial update)
field_2: new_value, ← opsional
"{detail_table}": { ← opsional
"insert": [ {...}, {...} ], ← opsional
"update": [ {...}, {...} ], ← opsional
"delete": [ {...}, {...} ] ← opsional
}
}
}| Komponen | Keterangan |
|---|---|
| Root key | Nama tabel header (contoh: stock_inbound) |
| Primary key header | Wajib disertakan untuk identifikasi record |
| Field header | Opsional, hanya field yang dikirim yang diperbarui |
| Object detail | Opsional, berisi operasi insert, update, dan/atau delete |
Properti detail pada request update-composite berupa object (bukan array). Object ini memiliki tiga sub-properti opsional: insert, update, dan delete. Setiap sub-properti berupa array of object.
Operasi Detail (Detail Operations)
| Operasi | Tipe | Keterangan |
|---|---|---|
insert | array | Item baru yang akan ditambahkan. Primary key dan foreign key di-generate otomatis |
update | array | Item yang akan diperbarui. Primary key detail wajib disertakan pada setiap object |
delete | array | Item yang akan dihapus. Primary key detail wajib disertakan pada setiap object |
Contoh Request (Request Example)
{
"stock_inbound": {
"stock_inbound_id": "a1b2c3d4-0000-0000-0000-000000000000",
"notes": "Updated delivery notes",
"stock_inbound_item": {
"delete": [
{
"stock_inbound_item_id": "e5f6a7b8-0000-0000-0000-000000000002"
}
],
"update": [
{
"stock_inbound_item_id": "e5f6a7b8-0000-0000-0000-000000000001",
"qty_received": 30,
"unit_price": 480000
}
],
"insert": [
{
"line_number": 3,
"item_product_id": "26f93e84-0000-0000-0000-000000000000",
"qty_received": 15,
"uom": "pcs",
"unit_price": 600000
}
]
}
}
}Update header saja (tanpa operasi detail):
{
"stock_inbound": {
"stock_inbound_id": "a1b2c3d4-0000-0000-0000-000000000000",
"notes": "Revised delivery schedule",
"warehouse_id": "d2000000-0000-0000-0000-000000000000"
}
}Body Options
Endpoint /update-composite mendukung format request body alternatif {data, options} untuk mengirimkan opsi tambahan yang dapat dibaca oleh component handler dan processor. Detail lengkap tersedia di halaman Body Options.
{
"data": {
"stock_inbound": {
"stock_inbound_id": "a1b2c3d4-0000-0000-0000-000000000000",
"notes": "Updated delivery notes",
"stock_inbound_item": {
"update": [
{
"stock_inbound_item_id": "e5f6a7b8-0000-0000-0000-000000000001",
"qty_received": 30
}
]
}
}
},
"options": {
"recalculate_stock": true
}
}Urutan Eksekusi (Execution Order)
Operasi detail dijalankan dalam urutan tetap berikut, terlepas dari urutan properti dalam request body:
1. DELETE — Hapus detail item yang ada di array delete
2. UPDATE — Perbarui detail item yang ada di array update
3. INSERT — Sisipkan detail item baru dari array insert
4. RECALCULATE — Hitung ulang field agregasi (jika dikonfigurasi)
5. UPDATE HEADER — Perbarui record header (field + hasil kalkulasi)
6. COMMIT — Commit transaksiUrutan DELETE → UPDATE → INSERT dipilih untuk menghindari konflik constraint. Menghapus item terlebih dahulu membebaskan unique constraint yang mungkin diperlukan oleh item baru yang akan di-insert.
Format Response (Response Format)
Response Sukses (Success Response)
HTTP 200 OK
Response menyertakan properti _operations yang merangkum jumlah operasi detail yang berhasil dijalankan.
{
"success": true,
"message": "stock_inbound data successfully updated",
"data": {
"stock_inbound_id": "a1b2c3d4-0000-0000-0000-000000000000",
"inbound_number": "INB/2026/001",
"inbound_date": "2026-04-16",
"supplier_id": "b1000000-0000-0000-0000-000000000000",
"warehouse_id": "d1000000-0000-0000-0000-000000000000",
"notes": "Updated delivery notes",
"total_items": 2,
"total_qty": 45,
"total_amount": 23400000,
"updated_at": "2026-04-16T10:30:00.000Z",
"updated_by": "Update from API",
"_operations": {
"deleted": 1,
"updated": 1,
"inserted": 1
}
},
"timestamp": "2026-04-16T10:30:00.000Z"
}Response Error (Error Responses)
400 — Root key tidak sesuai:
{
"success": false,
"error": "Invalid payload",
"message": "Root key must be 'stock_inbound'",
"timestamp": "2026-04-16T10:30:00.000Z"
}400 — Primary key header tidak ditemukan:
{
"success": false,
"error": "Invalid payload",
"message": "Primary key is required for update",
"timestamp": "2026-04-16T10:30:00.000Z"
}400 — Format detail tidak valid:
{
"success": false,
"error": "Invalid payload",
"message": "Detail must be an object with insert, update, or delete arrays",
"timestamp": "2026-04-16T10:30:00.000Z"
}400 — Primary key detail tidak ditemukan pada operasi update/delete:
{
"success": false,
"error": "Invalid payload",
"message": "Primary key is required for each detail item in update/delete operation",
"timestamp": "2026-04-16T10:30:00.000Z"
}404 — Record header tidak ditemukan:
{
"success": false,
"error": "Not found",
"message": "Record not found",
"timestamp": "2026-04-16T10:30:00.000Z"
}409 — Duplicate key:
{
"success": false,
"error": "Duplicate entry",
"message": "Inbound number already exists",
"timestamp": "2026-04-16T10:30:00.000Z"
}500 — Server error:
{
"success": false,
"error": "Internal server error",
"message": "An unexpected error occurred",
"timestamp": "2026-04-16T10:30:00.000Z"
}Kalkulasi Ulang Otomatis (Auto Recalculate)
Jika konfigurasi kalkulasi diaktifkan di payload, sistem menjalankan perhitungan ulang secara otomatis setelah seluruh operasi detail selesai. Proses kalkulasi ulang mencakup:
Level detail item:
| Kalkulasi | Contoh Formula |
|---|---|
| Perkalian field | amount = qty_received * unit_price |
Level header (agregasi dari detail yang tersisa):
| Kalkulasi | Contoh Formula |
|---|---|
| Count detail | total_items = COUNT(stock_inbound_item) |
| Sum field | total_qty = SUM(qty_received) |
| Sum field | total_amount = SUM(amount) |
Kalkulasi ulang dilakukan berdasarkan state akhir detail item setelah seluruh operasi delete, update, dan insert selesai dijalankan. Hasil kalkulasi di-update ke record header sebelum transaksi di-commit.
Perilaku Cache (Cache Behavior)
Setelah operasi update-composite berhasil, seluruh cache terkait endpoint ini di-invalidasi secara otomatis. Hal ini memastikan endpoint /read, /datatables, dan /lookup mengembalikan data terbaru pada request berikutnya.
Langkah Selanjutnya (Next Steps)
- POST /read-composite untuk mengambil data header beserta detail yang telah diperbarui
- POST /create-composite untuk membuat data header beserta detail baru
- Kode Error untuk referensi lengkap HTTP status code