Spaces:
Sleeping
Backend Go API Contract
Last updated: 2026-07-13
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 private object 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.
blob_name dipertahankan untuk kompatibilitas response lama, tetapi secara kontrak frontend harus dipahami sebagai stored object reference di private object storage, bukan Azure-specific blob URL.
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 private object 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 object storage.
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 private object 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": "object-storage/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}
Soft-delete analysis milik user: mengubah status menjadi inactive, bukan menghapus row dari database. Record analysis dan seluruh data terkait (reports, messages, report_inputs, dll) tetap ada di database, hanya tidak muncul lagi di GET /api/v1/analyses dengan filter default (status=active).
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": "uuid-dari-db",
"message_id": "uuid-dari-db",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "user",
"content": "Apa penyebab revenue turun di Q3?",
"status": "success",
"note": "",
"created_at": "2026-06-30T08:00:00Z"
}
role hanya:
user: pertanyaan atau instruksi dari userai: jawaban dari AI Agent Service
status hanya:
success: pesan tersimpan sesuai konten yang dikirim. Untukrole=user,message_idselalu system-generated (default), berapa pun nilaimessage_idyang dikirim frontend (jika ada) β nilai kiriman itu diabaikan. Untukrole=ai,successberartimessage_idyang dikirim valid dan dipakai apa adanya.failed: khususrole=aiyang dikirim tanpamessage_idvalid (lihat catatan di bawah).contentdiganti pesan fallback hardcoded danmessage_iddiganti default reserved value.
note hanya terisi (non-empty) ketika status=failed, berisi penjelasan singkat penyebab kegagalan. Saat status=success, field ini kosong/absent.
POST /api/v1/analyses/{id}/messages
Merekam tepat satu pesan conversation ke analyses_messages.
Request untuk pertanyaan user β jangan kirim message_id; jika dikirim tetap akan diabaikan sepenuhnya dan diganti dengan nilai default (system-generated):
{
"role": "user",
"content": "Apa penyebab revenue turun di Q3?"
}
Request untuk jawaban AI β message_id wajib diisi untuk role=ai:
{
"role": "ai",
"content": "Revenue turun karena penurunan transaksi enterprise dan kenaikan churn di wilayah barat.",
"message_id": "uuid-yang-dibuat-frontend-atau-agent-service"
}
Success 201 (role=user, atau role=ai dengan message_id valid):
{
"status": "success",
"message": "Message created",
"data": {
"message": {
"id": "uuid-dari-db",
"message_id": "uuid-dari-db",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "user",
"content": "Apa penyebab revenue turun di Q3?",
"status": "success",
"created_at": "2026-06-30T08:00:00Z"
}
}
}
message_idbernilai sama denganiduntuk pesan sukses (baikrole=usermaupunrole=aidenganmessage_idvalid) β disertakan agar frontend dapat langsung menggunakannya untuk memanggil endpoint observability (GET /api/v1/observability?analysis_id=...&message_id=...) tanpa mapping tambahan.
Kasus role=ai tanpa message_id (missing atau blank): endpoint tetap mengembalikan 201 (bukan error) karena kegagalan ini dianggap outcome data-level, bukan request error. Response menunjukkan status: "failed":
{
"status": "success",
"message": "Message created",
"data": {
"message": {
"id": "uuid-dari-db",
"message_id": "00000000-0000-0000-0000-000000000000",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "ai",
"content": "Maaf, terjadi kesalahan saat memproses respons AI. Silakan coba lagi.",
"status": "failed",
"note": "message_id is required for AI-role messages but was not provided",
"created_at": "2026-06-30T08:01:00Z"
}
}
}
message_id: "00000000-0000-0000-0000-000000000000" adalah nilai reserved yang dipakai berulang untuk setiap pesan ai yang gagal (bukan di-generate baru setiap kali) β jangan gunakan nilai ini untuk memanggil endpoint observability, karena tidak menunjuk ke jawaban AI yang valid. Chat tetap bisa dilanjutkan setelah kegagalan ini; tidak ada retry otomatis dari backend.
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": [
{
"id": "uuid-dari-db",
"message_id": "uuid-dari-db",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "ai",
"content": "Revenue turun karena penurunan transaksi enterprise.",
"status": "success",
"created_at": "2026-06-30T08:01:00Z"
},
{
"id": "uuid-dari-db-2",
"message_id": "00000000-0000-0000-0000-000000000000",
"analysis_id": "analysis-id",
"user_id": "user-id",
"role": "ai",
"content": "Maaf, terjadi kesalahan saat memproses respons AI. Silakan coba lagi.",
"status": "failed",
"note": "message_id is required for AI-role messages but was not provided",
"created_at": "2026-06-30T08:02:00Z"
}
]
}
}
Setiap item menyertakan
message_id,status, dan (jikafailed)note. Untuk pesanstatus=success,message_idsama denganiddan dapat dipakai memanggilGET /api/v1/observability?analysis_id=...&message_id=...setelah page refresh. Untuk pesanstatus=failed, gunakan field ini hanya untuk ditampilkan sebagai error bubble di UI β jangan dipakai memanggil observability endpoint.
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, content=agent_answer, message_id=agent_message_id
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.
- Saat merekam jawaban AI (
role=ai), selalu sertakanmessage_iddari AI Agent Service. Jikamessage_idtidak dikirim atau kosong, endpoint tetap sukses (201) tetapi menyimpan pesan denganstatus: "failed",contentfallback hardcoded, danmessage_idreserved (00000000-0000-0000-0000-000000000000) β frontend harus memeriksastatuspada response, bukan hanya HTTP status code, untuk mendeteksi kegagalan ini. - Saat merekam pertanyaan user (
role=user), jangan mengirimmessage_idsama sekali β backend selalu mengabaikannya dan memakai nilai default (system-generated) untukrole=user, tidak peduli apa yang dikirim frontend.