RESTForge

POST /create-composite

Spesifikasi endpoint create-composite untuk operasi master-detail

Endpoint /create-composite digunakan untuk menyisipkan data header (master) beserta detail item 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)

PropertiNilai
MethodPOST
URL/api/{project}/{endpoint}/create-composite
Content-Typeapplication/json
Status Sukses201 Created
DatabasePostgreSQL, MySQL, Oracle
TransaksiAtomik (header + detail dalam satu transaksi)
CacheInvalidasi otomatis setelah create berhasil
Event LifecycleonBeforeInsert → INSERT header → INSERT details → onAfterInsert

Ikhtisar (Overview)

Endpoint ini dirancang untuk skenario master-detail seperti invoice dengan item, purchase order dengan line item, atau stock inbound dengan detail barang. Dalam satu request, data header di-insert terlebih dahulu, kemudian seluruh detail item di-insert secara berurutan. Jika terjadi kegagalan pada tahap manapun, seluruh transaksi di-rollback untuk menjaga konsistensi (consistency) data.

Primary key untuk header dan setiap detail item di-generate otomatis sebagai UUID. Foreign key pada detail item yang mereferensikan header juga diisi secara otomatis dari primary key header yang baru dibuat.

Format Request (Request Format)

Struktur Bersarang (Nested Structure)

Request body menggunakan struktur bersarang di mana root key adalah nama tabel header. Di dalam object header, terdapat array dengan nama tabel detail yang berisi item-item detail.

{
    "{header_table}": {
        field_1: value,
        field_2: value,
        "{detail_table}": [
            { detail_field_1: value, detail_field_2: value },
            { detail_field_1: value, detail_field_2: value }
        ]
    }
}
KomponenKeterangan
Root keyNama tabel header (contoh: stock_inbound)
Field headerPasangan field-value untuk record header
Array detailArray object berisi item-item detail, menggunakan nama tabel detail sebagai key

Root key pada request body harus sesuai dengan nama tabel header yang dikonfigurasi di payload. Jika root key tidak cocok, server mengembalikan response error 400.

Contoh Request (Request Example)

POST /api/mini-inventory/stock-inbound/create-composite
{
    "stock_inbound": {
        "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": "First batch delivery",
        "stock_inbound_item": [
            {
                "line_number": 1,
                "item_product_id": "04d71c62-0000-0000-0000-000000000000",
                "qty_received": 25,
                "uom": "pcs",
                "unit_price": 500000
            },
            {
                "line_number": 2,
                "item_product_id": "15e82d73-0000-0000-0000-000000000000",
                "qty_received": 10,
                "uom": "pcs",
                "unit_price": 750000
            }
        ]
    }
}

Body Options

Endpoint /create-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.

POST /api/mini-inventory/stock-inbound/create-composite
{
    "data": {
        "stock_inbound": {
            "inbound_number": "INB/2026/001",
            "inbound_date": "2026-04-16",
            "supplier_id": "b1000000-0000-0000-0000-000000000000",
            "warehouse_id": "d1000000-0000-0000-0000-000000000000",
            "stock_inbound_item": [
                {
                    "line_number": 1,
                    "item_product_id": "04d71c62-0000-0000-0000-000000000000",
                    "qty_received": 25,
                    "uom": "pcs",
                    "unit_price": 500000
                }
            ]
        }
    },
    "options": {
        "auto_approve": false
    }
}

Format Response (Response Format)

Response Sukses (Success Response)

HTTP 201 Created

{
    "success": true,
    "message": "stock_inbound data successfully added",
    "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": "First batch delivery",
        "total_items": 2,
        "total_qty": 35,
        "total_amount": 20000000,
        "created_at": "2026-04-16T10:30:00.000Z",
        "created_by": "Input from API",
        "stock_inbound_item": [
            {
                "stock_inbound_item_id": "e5f6a7b8-0000-0000-0000-000000000001",
                "stock_inbound_id": "a1b2c3d4-0000-0000-0000-000000000000",
                "line_number": 1,
                "item_product_id": "04d71c62-0000-0000-0000-000000000000",
                "qty_received": 25,
                "uom": "pcs",
                "unit_price": 500000,
                "amount": 12500000,
                "created_at": "2026-04-16T10:30:00.000Z",
                "created_by": "Input from API"
            },
            {
                "stock_inbound_item_id": "e5f6a7b8-0000-0000-0000-000000000002",
                "stock_inbound_id": "a1b2c3d4-0000-0000-0000-000000000000",
                "line_number": 2,
                "item_product_id": "15e82d73-0000-0000-0000-000000000000",
                "qty_received": 10,
                "uom": "pcs",
                "unit_price": 750000,
                "amount": 7500000,
                "created_at": "2026-04-16T10:30:00.000Z",
                "created_by": "Input from API"
            }
        ]
    },
    "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 — Array detail kosong:

{
    "success": false,
    "error": "Invalid payload",
    "message": "Detail items cannot be empty",
    "timestamp": "2026-04-16T10:30:00.000Z"
}

400 — Validasi gagal:

{
    "success": false,
    "error": "Validation failed",
    "message": "Invalid data",
    "errors": {
        "inbound_number": ["Field inbound_number is required"],
        "stock_inbound_item[0].qty_received": ["Field qty_received must be greater than 0"]
    },
    "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"
}

Field Otomatis (Auto-Populated Fields)

FieldNilaiKeterangan
Header primary keyUUID v4Di-generate otomatis untuk record header
Detail primary keyUUID v4Di-generate otomatis untuk setiap record detail
Detail foreign keyUUID headerDiisi otomatis dari primary key header yang baru dibuat
created_atTimestamp saat iniDi-set pada header dan setiap detail
created_by"Input from API"Di-set pada header dan setiap detail

Kalkulasi Otomatis (Auto Calculate)

Jika konfigurasi kalkulasi diaktifkan di payload, sistem menjalankan perhitungan otomatis pada dua level:

Level detail item:

KalkulasiContoh Formula
Perkalian fieldamount = qty_received * unit_price

Level header (agregasi dari detail):

KalkulasiContoh Formula
Count detailtotal_items = COUNT(stock_inbound_item)
Sum fieldtotal_qty = SUM(qty_received)
Sum fieldtotal_amount = SUM(amount)

Kalkulasi otomatis dijalankan setelah seluruh detail item berhasil di-insert. Hasil kalkulasi level header kemudian di-update ke record header sebelum transaksi di-commit.

Perilaku Cache (Cache Behavior)

Setelah operasi create-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)

On this page