# Frontend API Contract
Dokumen ini merangkum endpoint Orchestration Agent Service yang dipakai oleh frontend. Fokus flow:
- User login dan menyimpan token.
- User menyiapkan knowledge source: upload/proses file, connect database, ingest schema, dan rebuild data catalog.
- Setelah knowledge siap, user membuat
new analysisdengan judul, objective, business question, dan data source binding. - Frontend mengirim pertanyaan ke AI Agent Service terpisah.
- Service ini hanya merekam riwayat tanya jawab ke
analyses_messages.
Base URL lokal contoh: http://localhost:8080
Konvensi
Semua endpoint protected wajib memakai:
Authorization: Bearer <access_token>
Endpoint public:
GET /healthPOST /api/loginPOST /api/refresh
Sebagian besar response memakai envelope:
{
"status": "success",
"message": "human-readable message",
"data": {}
}
Error response:
{
"status": "error",
"message": "error message",
"data": {
"code": "OPTIONAL_ERROR_CODE"
}
}
Catatan ownership: beberapa endpoint masih menerima user_id di body, path, atau query untuk kompatibilitas. Nilainya wajib sama dengan user dari Bearer token.
Flow Frontend
1. Login
Frontend memanggil POST /api/login, lalu simpan:
data.user.idsebagaiuser_iddata.access_tokenuntuk header Bearerdata.refresh_tokenuntuk refresh token rotation
access_token berlaku 1 jam. refresh_token berlaku 7 hari dan akan diganti setiap kali refresh sukses.
2. Refresh Token
Jika request protected menerima 401 karena token expired, panggil POST /api/refresh menggunakan refresh token terakhir. Setelah sukses, ganti access token dan refresh token lama dengan token baru dari response.
Refresh token lama tidak boleh dipakai lagi setelah refresh sukses.
3. Menyiapkan Knowledge Source
Frontend dapat menyediakan knowledge source dari dokumen dan/atau database.
Untuk dokumen:
- Ambil tipe file yang didukung:
GET /api/v1/documents/doctypes - Upload file:
POST /api/v1/document/upload - Proses dokumen:
POST /api/v1/document/process - Pantau status dokumen:
GET /api/v1/documents/{user_id}
Untuk database:
- Ambil tipe database dan schema form:
GET /api/v1/database-clients/dbtypes - Simpan koneksi database:
POST /api/v1/database-clients - Ingest schema database:
POST /api/v1/database-clients/{client_id}/ingest?user_id={user_id} - Pantau koneksi:
GET /api/v1/database-clients/{user_id}
Setelah dokumen/database siap, frontend dapat rebuild dan membaca user data catalog:
POST /api/v1/data-catalog/rebuildGET /api/v1/data-catalog/{user_id}
4. Membuat New Analysis
Frontend menampilkan form:
analysis_titleobjectivebusiness_questionsdata_bind
POST /api/v1/analyses wajib menerima analysis_title, objective, business_questions, dan data_bind. business_questions berbentuk array string karena satu analysis dapat membawa lebih dari satu pertanyaan bisnis awal.
Flow yang direkomendasikan:
POST /api/v1/analysesdengan title, objective, business_questions, dan data_bind.- Ambil
data.iddari response sebagaianalysis_id. - Frontend memanggil AI Agent Service terpisah memakai context analysis, business_questions, dan catalog.
- Saat user mulai bertanya ke AI Agent Service, rekam pertanyaan dengan
role=userke endpoint messages. - Setelah AI Agent Service menjawab, simpan jawaban dengan
role=aike endpoint messages.
5. Conversation Recording
Endpoint message di service ini tidak memanggil AI agent, tidak melakukan reasoning, dan tidak membuat balasan otomatis.
Frontend bertanggung jawab melakukan dua write terpisah:
- Rekam pertanyaan user:
{
"role": "user",
"content": "Apa penyebab revenue turun di Q3?"
}
- Setelah AI Agent Service menjawab, rekam jawaban agent:
{
"role": "ai",
"content": "Revenue Q3 turun terutama karena penurunan volume transaksi di segmen enterprise..."
}
Endpoint Ringkas
| Method | Path | Kegunaan |
|---|---|---|
GET |
/health |
Health check service |
POST |
/api/login |
Login dan issue token pair |
POST |
/api/refresh |
Rotate refresh token dan issue token pair baru |
GET |
/api/v1/documents/doctypes |
List tipe dokumen yang didukung |
POST |
/api/v1/document/upload |
Upload dokumen ke Azure Blob Storage |
POST |
/api/v1/document/upload-local |
Upload dokumen ke local filesystem untuk benchmark |
POST |
/api/v1/document/process |
Proses dokumen async |
GET |
/api/v1/documents/{user_id} |
List dokumen milik user |
DELETE |
/api/v1/document/delete |
Hapus dokumen |
GET |
/api/v1/database-clients/dbtypes |
List tipe database dan schema credential form |
POST |
/api/v1/database-clients |
Buat koneksi database |
GET |
/api/v1/database-clients/{user_id} |
List koneksi database user |
GET |
/api/v1/database-clients/{user_id}/{client_id} |
Detail koneksi database |
PUT |
/api/v1/database-clients/{client_id} |
Update koneksi database |
DELETE |
/api/v1/database-clients/{client_id} |
Hapus koneksi database |
POST |
/api/v1/database-clients/{client_id}/ingest |
Introspect schema database ke catalog |
POST |
/api/v1/data-catalog/rebuild |
Rebuild user data catalog |
GET |
/api/v1/data-catalog/{user_id} |
Ambil user data catalog index |
POST |
/api/v1/analyses |
Buat analysis baru |
GET |
/api/v1/analyses |
List analysis user |
GET |
/api/v1/analyses/{id} |
Detail analysis |
PATCH |
/api/v1/analyses/{id} |
Update metadata/status analysis |
DELETE |
/api/v1/analyses/{id} |
Hapus analysis |
PUT |
/api/v1/analyses/{id}/data-bind |
Update data source binding analysis |
GET |
/api/v1/analyses/{id}/data-catalog |
Ambil catalog yang scoped ke analysis |
POST |
/api/v1/analyses/{id}/data-catalog/rebuild |
Rebuild catalog scoped ke analysis dari data_bind |
GET |
/api/v1/analyses/{id}/messages |
Ambil riwayat pesan analysis |
POST |
/api/v1/analyses/{id}/messages |
Rekam satu pesan conversation |
Auth
POST /api/login
Login user dengan email dan password.
Request:
{
"email": "user@example.com",
"password": "password"
}
Success 200:
{
"status": "success",
"message": "login successful",
"data": {
"user": {
"id": "user-id",
"email": "user@example.com",
"fullname": "User Name",
"role": "user",
"status": "active"
},
"access_token": "jwt-access-token",
"refresh_token": "opaque-refresh-token",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_expires_in": 604800
}
}
Errors: 400, 401, 403, 404, 500.
POST /api/refresh
Menukar refresh token aktif dengan token pair baru.
Request:
{
"refresh_token": "opaque-refresh-token"
}
Success 200 mengembalikan bentuk data yang sama dengan login, berisi user, access token baru, refresh token baru, token_type, expires_in, dan refresh_expires_in.
Errors: 400, 401, 403, 500.
Documents
Document Model
{
"id": "document-id",
"user_id": "user-id",
"filename": "sales.csv",
"blob_name": "user-id/document-id/sales.csv",
"file_size": 2048,
"file_type": "csv",
"status": "uploaded",
"chunks_count": 0,
"processed_at": "2026-06-30T08:00:00Z",
"error_message": null,
"created_at": "2026-06-30T08:00:00Z"
}
Status umum: uploaded, processing, processed, failed.
GET /api/v1/documents/doctypes
Mengambil tipe dokumen yang didukung.
Success 200:
{
"status": "success",
"message": "supported document types",
"data": [
{
"type": "pdf",
"max_size_mb": 10,
"status": "active",
"message": null
}
]
}
POST /api/v1/document/upload
Upload dokumen ke Azure Blob Storage. Maksimum 10 MB. Mendukung pdf, docx, txt, csv, dan xlsx.
Content-Type: multipart/form-data
Form fields:
| Field | Required | Keterangan |
|---|---|---|
user_id |
Yes | Harus sama dengan user dari token |
file |
Yes | File dokumen |
Success 201: data berisi Document Model.
Errors: 400, 401, 403, 429, 500.
POST /api/v1/document/upload-local
Upload file ke filesystem lokal untuk benchmarking. Kontrak form sama dengan upload Azure.
Success 201:
{
"status": "success",
"message": "file saved locally",
"data": {
"path": "files/user-id/sales.csv"
}
}
POST /api/v1/document/process
Memulai proses dokumen secara async. Untuk dokumen unstructured, service melakukan extract text dan embedding jika tersedia. Untuk dokumen tabular, service membuat parquet/catalog source.
Request:
{
"document_id": "document-id",
"user_id": "user-id"
}
Success 202:
{
"status": "success",
"message": "document processing started",
"data": {
"document_id": "document-id",
"file_type": "csv",
"status": "processing"
}
}
Pantau hasilnya lewat GET /api/v1/documents/{user_id}.
Errors: 400, 401, 403, 404, 500.
GET /api/v1/documents/{user_id}
List dokumen milik user.
Success 200:
{
"status": "success",
"message": "documents",
"data": []
}
Errors: 401, 403, 500.
DELETE /api/v1/document/delete
Menghapus dokumen dari storage, embedding/parquet terkait, dan record database.
Request:
{
"document_id": "document-id",
"user_id": "user-id"
}
Success 200:
{
"status": "success",
"message": "document deleted"
}
Errors: 400, 401, 403, 404, 500.
Database Clients
DB Client Model
{
"id": "client-id",
"user_id": "user-id",
"name": "Analytics Warehouse",
"db_type": "postgres",
"status": "active",
"created_at": "2026-06-30T08:00:00Z",
"updated_at": "2026-06-30T08:00:00Z"
}
GET /api/v1/database-clients/dbtypes
Mengambil tipe database dan daftar field credential untuk render form dinamis. Saat ini postgres aktif; tipe lain dapat muncul sebagai inactive.
POST /api/v1/database-clients
Menyimpan koneksi database. Credentials disimpan terenkripsi. Jika koneksi dengan identity yang sama sudah ada, response 200 mengembalikan client existing.
Request:
{
"user_id": "user-id",
"name": "Analytics Warehouse",
"db_type": "postgres",
"credentials": {
"host": "db.example.com",
"port": 5432,
"database": "analytics",
"username": "db_user",
"password": "db_password",
"ssl_mode": "require"
}
}
Success:
201: database client created200: database client already exists
Errors: 400, 401, 403, 429, 500.
GET /api/v1/database-clients/{user_id}
List koneksi database milik user.
Success 200:
{
"status": "success",
"message": "database clients",
"data": []
}
Errors: 401, 403, 500.
GET /api/v1/database-clients/{user_id}/{client_id}
Ambil detail satu koneksi database. Success 200 dengan data berisi DB Client Model.
Errors: 401, 403, 404, 500.
PUT /api/v1/database-clients/{client_id}?user_id={user_id}
Update nama, credentials, atau status koneksi. Semua field body optional, tetapi body harus JSON valid.
Request:
{
"name": "Updated Warehouse",
"credentials": {
"host": "db.example.com",
"port": 5432,
"database": "analytics",
"username": "db_user",
"password": "new_password",
"ssl_mode": "require"
},
"status": "active"
}
Success 200: data berisi DB Client Model.
Errors: 400, 401, 403, 404, 500.
DELETE /api/v1/database-clients/{client_id}?user_id={user_id}
Menghapus koneksi database dan memicu pembersihan catalog.
Success 200:
{
"status": "success",
"message": "database client deleted"
}
Errors: 400, 401, 403, 404, 500.
POST /api/v1/database-clients/{client_id}/ingest?user_id={user_id}
Melakukan introspection schema database dan menyimpan hasilnya ke catalog. Tidak membutuhkan request body.
Success 200:
{
"status": "success",
"message": "schema ingested",
"data": {
"tables": []
}
}
Errors: 400, 401, 403, 404, 409, 429, 500.
Data Catalog
POST /api/v1/data-catalog/rebuild
Rebuild seluruh catalog user dari dokumen tabular dan database client aktif.
Request:
{
"user_id": "user-id"
}
Success 200:
{
"status": "success",
"message": "catalog rebuilt",
"data": {
"user_id": "user-id",
"schema_version": "1.0",
"generated_at": "2026-06-30T08:00:00Z",
"sources": []
}
}
Errors: 400, 401, 403, 429, 500.
GET /api/v1/data-catalog/{user_id}
Mengambil index catalog user. Response sources berisi ringkasan source, tanpa detail table penuh.
Success 200:
{
"status": "success",
"message": "data catalog",
"data": {
"user_id": "user-id",
"schema_version": "1.0",
"generated_at": "2026-06-30T08:00:00Z",
"sources": [
{
"source_id": "document-or-client-id",
"source_type": "tabular",
"name": "sales.csv",
"location_ref": "blob/path/or/db-ref",
"table_count": 1,
"updated_at": "2026-06-30T08:00:00Z"
}
]
}
}
Errors: 401, 403, 500.
POST /api/v1/analyses/{id}/data-catalog/rebuild
Membangun ulang catalog khusus analysis berdasarkan data_bind terbaru milik analysis tersebut. Endpoint ini hanya memakai source yang ter-bind ke analysis, bukan semua knowledge source user.
Gunakan endpoint ini setelah perubahan binding jika frontend ingin memicu rebuild secara eksplisit. PUT /api/v1/analyses/{id}/data-bind juga melakukan rebuild analysis catalog sebagai bagian dari update binding.
Tidak membutuhkan request body.
Success 200:
{
"status": "success",
"message": "analysis catalog rebuilt",
"data": {
"user_id": "user-id",
"schema_version": "1.0",
"generated_at": "2026-06-30T08:00:00Z",
"sources": []
}
}
Errors: 400, 401, 404, 500.
GET /api/v1/analyses/{id}/data-catalog
Mengambil catalog yang scoped ke analysis dan mengikuti data_bind analysis, bukan seluruh catalog user.
Success 200:
{
"status": "success",
"message": "analysis data catalog",
"data": {
"user_id": "user-id",
"schema_version": "1.0",
"generated_at": "2026-06-30T08:00:00Z",
"sources": []
}
}
Errors: 401, 404.
Analyses
Data Bind Item
data_bind adalah daftar source yang dipilih user untuk analysis.
{
"id": "source-id",
"name": "sales.csv",
"group_type": "document",
"type": "csv"
}
Field:
| Field | Required | Keterangan |
|---|---|---|
id |
Yes | document.id atau database_client.id |
name |
Yes | Nama yang ditampilkan di UI |
group_type |
Yes | document atau database |
type |
Yes | File type (csv, pdf, xlsx) atau database type (postgres) |
Rules:
data_bindwajib berisi minimal satu source.- Semua source harus milik user yang sedang login.
- Duplicate source dalam satu
data_bindditolak.
Analysis Model
{
"id": "analysis-id",
"user_id": "user-id",
"analysis_title": "Q3 Revenue Analysis",
"objective": "Find revenue movement and root cause",
"business_questions": [
"Why did revenue drop in Q3?",
"Which customer segment contributed the most to the change?"
],
"status": "active",
"data_bind": [
{
"id": "document-id",
"name": "sales.csv",
"group_type": "document",
"type": "csv"
}
],
"data_bind_version": 1,
"report_collection": [],
"created_at": "2026-06-30T08:00:00Z",
"updated_at": "2026-06-30T08:00:00Z"
}
POST /api/v1/analyses
Membuat analysis aktif dengan source binding awal.
Request:
{
"analysis_title": "Q3 Revenue Analysis",
"objective": "Find revenue movement and root cause",
"business_questions": [
"Why did revenue drop in Q3?",
"Which customer segment contributed the most to the change?"
],
"data_bind": [
{
"id": "document-id",
"name": "sales.csv",
"group_type": "document",
"type": "csv"
},
{
"id": "database-client-id",
"name": "Analytics Warehouse",
"group_type": "database",
"type": "postgres"
}
]
}
Success 201: data berisi Analysis Model.
Validation:
business_questionswajib berisi minimal satu string non-empty.data_bindwajib berisi minimal satu source.
Errors: 400, 401, 409.
GET /api/v1/analyses
List analysis milik user.
Query:
| Query | Default | Keterangan |
|---|---|---|
status |
active |
active atau inactive |
page |
1 |
Nomor halaman |
limit |
20 |
Maksimum 100 |
Success 200:
{
"status": "success",
"message": "Analyses retrieved",
"data": {
"analyses": [],
"pagination": {
"page": 1,
"limit": 20
}
}
}
Errors: 401, 500.
GET /api/v1/analyses/{id}
Ambil detail analysis milik user. Success 200 dengan data berisi Analysis Model.
Errors: 400, 401, 404.
PATCH /api/v1/analyses/{id}
Update metadata analysis. Field optional.
Request:
{
"analysis_title": "Updated title",
"objective": "Updated objective",
"status": "inactive"
}
status hanya active atau inactive.
Success 200: data berisi Analysis Model.
Errors: 400, 401, 404.
DELETE /api/v1/analyses/{id}
Hapus analysis milik user.
Success 204 tanpa response body.
Errors: 400, 401, 404.
PUT /api/v1/analyses/{id}/data-bind
Mengganti daftar source yang ter-bind ke analysis secara atomic dengan optimistic version check. Jika update berhasil, service juga rebuild catalog scope analysis dari data_bind terbaru. Jika rebuild catalog gagal, perubahan binding ditolak/rollback.
Request:
{
"expected_version": 1,
"data_bind": [
{
"id": "new-document-id",
"name": "updated-sales.csv",
"group_type": "document",
"type": "csv"
}
]
}
Success 200: data berisi Analysis Model dengan data_bind_version yang sudah naik.
Errors:
400: payload invalid, empty binding, source invalid401: token invalid/missing409: staleexpected_version, inactive analysis, atau limit violation
Analysis Messages
Message Model
{
"id": "message-id",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "user",
"content": "Apa penyebab revenue turun di Q3?",
"created_at": "2026-06-30T08:00:00Z"
}
role hanya:
user: pertanyaan atau instruksi dari userai: jawaban dari AI Agent Service
POST /api/v1/analyses/{id}/messages
Merekam tepat satu pesan conversation ke analyses_messages.
Request untuk pertanyaan user:
{
"role": "user",
"content": "Apa penyebab revenue turun di Q3?"
}
Request untuk jawaban AI:
{
"role": "ai",
"content": "Revenue turun karena penurunan transaksi enterprise dan kenaikan churn di wilayah barat."
}
Success 201:
{
"status": "success",
"message": "Message created",
"data": {
"message": {
"id": "message-id",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "user",
"content": "Apa penyebab revenue turun di Q3?",
"created_at": "2026-06-30T08:00:00Z"
}
}
}
Errors:
400: invalid role/content, invalid analysis ID401: token invalid/missing409: inactive analysis atau message limit tercapai
GET /api/v1/analyses/{id}/messages
Mengambil riwayat conversation analysis.
Query:
| Query | Default | Keterangan |
|---|---|---|
limit |
100 |
Maksimum 100 |
Success 200:
{
"status": "success",
"message": "Messages retrieved",
"data": {
"messages": []
}
}
Errors: 400, 401, 404.
Suggested Frontend Integration Sequence
Login
POST /api/login
store access_token, refresh_token, user.id
Upload and Process File
GET /api/v1/documents/doctypes
POST /api/v1/document/upload
POST /api/v1/document/process
GET /api/v1/documents/{user_id}
Connect Database
GET /api/v1/database-clients/dbtypes
POST /api/v1/database-clients
POST /api/v1/database-clients/{client_id}/ingest?user_id={user_id}
GET /api/v1/database-clients/{user_id}
Generate Knowledge Catalog
POST /api/v1/data-catalog/rebuild
GET /api/v1/data-catalog/{user_id}
Create Analysis and Start Conversation
POST /api/v1/analyses with business_questions
call AI Agent Service outside this service
POST /api/v1/analyses/{analysis_id}/messages with role=user and content=user_question
POST /api/v1/analyses/{analysis_id}/messages with role=ai and content=agent_answer
GET /api/v1/analyses/{analysis_id}/messages
Important Frontend Notes
- Jangan mengirim pesan user ke
POST /api/v1/analyses/{id}/messagesdengan ekspektasi service ini akan menjawab. Endpoint ini hanya persistence. - AI Agent Service adalah service terpisah. Service ini menyimpan metadata analysis, knowledge catalog, data binding, dan history conversation.
- User-level catalog berisi seluruh knowledge source user; analysis-level catalog hanya berisi source yang ada di
data_bindanalysis. - Perubahan
data_bindakan rebuild analysis-level catalog. Frontend juga dapat memanggil endpoint rebuild analysis catalog secara eksplisit jika diperlukan. - Setelah refresh token sukses, selalu replace refresh token lama dengan refresh token baru.
- Untuk endpoint yang membutuhkan
user_id, gunakandata.user.iddari login dan pastikan sama dengan token aktif. - Untuk binding analysis, pakai source yang sudah berhasil diupload/diproses atau database client yang sudah diingest.