Schema Builder API

API untuk membuat dan mengelola tabel transaksi milik tenant sendiri (DDL/DML) tanpa menulis SQL mentah.

Gambaran Umum

Schema Builder API memungkinkan tenant membuat dan mengelola tabel data miliknya sendiri di database AlurKerja — tanpa menulis SQL. Cocok dipakai SOP/integrasi eksternal yang butuh tabel transaksi kustom (mis. tabel yang dipakai bersama beberapa proses BPMN, atau data yang perlu dikelola lewat API alih-alih lewat form).

Setiap tenant punya schema database sendiri. API ini hanya mengizinkan operasi pada tabel yang dibuat lewat API ini sendiri — tabel bawaan sistem (mis. tabel transaksi otomatis per proses BPMN, lihat Tabel Transaksi Manual) tidak pernah bisa disentuh atau tertimpa oleh API ini.

Endpoint ini hanya bisa diakses oleh Admin SOP tenant (bukan Member biasa), karena bisa membuat/mengubah/menghapus tabel dan datanya.

Autentikasi

Semua endpoint butuh header Authorization: Bearer <token> (JWT AlurKerja, sama seperti endpoint API lain) dan :tenantId di path adalah ID tenant tujuan.

Tipe kolom yang didukung

Saat membuat tabel, tiap kolom harus salah satu dari tipe berikut:

Tipe (dikirim di request)Disimpan sebagai
textteks bebas panjang
integerbilangan bulat
bigintbilangan bulat besar
numericangka desimal presisi
booleanbenar/salah
datetanggal
timestamptanggal + jam (dengan timezone)
jsonbdata JSON bebas

Tiap tabel otomatis punya 3 kolom bawaan yang tidak perlu (dan tidak boleh) didefinisikan sendiri: id (primary key), created_at, updated_at.

Nama tabel dan nama kolom harus huruf kecil, diawali huruf, hanya huruf/angka/underscore (^[a-z][a-z0-9_]*$), maksimal 63 karakter.

Tabel

Buat tabel

POST /api/v1/report/{tenantId}/schema/tables
Request body
{
  "name": "penjualan_harian",
  "description": "Rekap penjualan harian per cabang",
  "columns": [
    { "name": "cabang", "type": "text", "nullable": false },
    { "name": "total", "type": "numeric", "nullable": false },
    { "name": "catatan", "type": "text", "nullable": true }
  ]
}
Response 201
{
  "success": true,
  "message": "Table created successfully",
  "data": {
    "id": 1,
    "table_name": "penjualan_harian",
    "columns": [
      { "name": "cabang", "type": "text", "nullable": false },
      { "name": "total", "type": "numeric", "nullable": false },
      { "name": "catatan", "type": "text", "nullable": true }
    ],
    "description": "Rekap penjualan harian per cabang",
    "created_at": "2026-09-23T10:00:00Z",
    "updated_at": "2026-09-23T10:00:00Z"
  }
}

Request ditolak (400) kalau nama tabel sudah dipakai tabel lain di schema tenant ini — baik tabel yang sudah dibuat lewat API ini sebelumnya, maupun tabel bawaan sistem (mis. tabel transaksi proses BPMN). Ini mencegah tabel baru menimpa data yang sudah ada.

Daftar tabel

GET /api/v1/report/{tenantId}/schema/tables

Mengembalikan semua tabel yang dibuat tenant ini lewat API ini (tabel bawaan sistem tidak ikut muncul).

Detail tabel

GET /api/v1/report/{tenantId}/schema/tables/{table}

Mengembalikan definisi kolom tabel. 404 kalau tabel tidak pernah dibuat lewat API ini (termasuk kalau nama itu adalah tabel bawaan sistem).

Hapus tabel

DELETE /api/v1/report/{tenantId}/schema/tables/{table}?confirm=true

Parameter confirm=true wajib — tanpa itu, request ditolak (400) dan tabel tidak disentuh sama sekali. Ini mencegah tabel terhapus tidak sengaja.

Data (rows)

Tambah data

POST /api/v1/report/{tenantId}/schema/tables/{table}/rows
Request body — bisa lebih dari satu baris sekaligus
{
  "rows": [
    { "cabang": "Surabaya", "total": 1250000, "catatan": null },
    { "cabang": "Malang", "total": 870500, "catatan": "termasuk diskon" }
  ]
}

Setiap baris dalam satu request harus punya kolom yang persis sama (tidak boleh baris 1 punya kolom catatan sementara baris 2 tidak).

Response 201
{ "success": true, "message": "Rows inserted successfully", "data": { "affected_rows": 2 } }

Lihat data

GET /api/v1/report/{tenantId}/schema/tables/{table}/rows?page=0&limit=50&cabang=Surabaya
  • page (default 0) dan limit (default 50, maksimal 500) untuk paginasi.
  • Parameter query lain diperlakukan sebagai filter kesamaan (kolom=nilai), boleh lebih dari satu (digabung dengan AND). Filter pada kolom yang tidak ada di tabel akan ditolak (400).
Response 200
{
  "success": true,
  "message": "Rows retrieved successfully",
  "data": {
    "rows": [
      { "id": 1, "cabang": "Surabaya", "total": 1250000, "catatan": null, "created_at": "...", "updated_at": "..." }
    ],
    "page": 0,
    "limit": 50,
    "total": 1
  }
}

Ubah data

PATCH /api/v1/report/{tenantId}/schema/tables/{table}/rows
Request body
{
  "where": { "cabang": "Surabaya" },
  "set": { "total": 1480000 }
}

where dan set wajib diisi (tidak boleh kosong) — endpoint ini sengaja tidak mendukung update ke seluruh baris sekaligus tanpa kondisi, supaya update yang salah tidak menimpa semua data.

Hapus data

DELETE /api/v1/report/{tenantId}/schema/tables/{table}/rows
Request body
{ "where": { "cabang": "Malang" } }

where wajib diisi untuk alasan yang sama dengan update — hapus seluruh baris di satu tabel tidak didukung endpoint ini (hapus tabelnya lewat endpoint Hapus Tabel kalau memang itu maksudnya).

Error yang umum terjadi

StatusPenyebab
400Body request tidak valid, tipe kolom tidak didukung, nama tabel/kolom melanggar aturan penamaan, atau kolom yang direferensikan (where/set/filter) tidak dikenal.
400Hapus tabel tanpa ?confirm=true.
401Token tidak ada/tidak valid, atau bukan Admin SOP.
404Tabel tidak ditemukan — tidak pernah dibuat lewat API ini untuk tenant tersebut.

Jejak audit

Setiap panggilan create/drop table, insert, update, dan delete tercatat (siapa, kapan, statement, berhasil/gagal) untuk keperluan audit internal. Kontak tim AlurKerja kalau butuh melihat riwayat perubahan sebuah tabel.