Agentic-Service-Data-Eyond-Catalog / API_CONTRACT_BE_GOLANG.md
ishaq101's picture
feat/ Endpoint Restructure (#5)
3bacc1d
|
Raw
History Blame Contribute Delete
22 kB

# Frontend API Contract

Dokumen ini merangkum endpoint Orchestration Agent Service yang dipakai oleh frontend. Fokus flow:

  1. User login dan menyimpan token.
  2. User menyiapkan knowledge source: upload/proses file, connect database, ingest schema, dan rebuild data catalog.
  3. Setelah knowledge siap, user membuat new analysis dengan judul, objective, business question, dan data source binding.
  4. Frontend mengirim pertanyaan ke AI Agent Service terpisah.
  5. 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 /health
  • POST /api/login
  • POST /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.id sebagai user_id
  • data.access_token untuk header Bearer
  • data.refresh_token untuk 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:

  1. Ambil tipe file yang didukung: GET /api/v1/documents/doctypes
  2. Upload file: POST /api/v1/document/upload
  3. Proses dokumen: POST /api/v1/document/process
  4. Pantau status dokumen: GET /api/v1/documents/{user_id}

Untuk database:

  1. Ambil tipe database dan schema form: GET /api/v1/database-clients/dbtypes
  2. Simpan koneksi database: POST /api/v1/database-clients
  3. Ingest schema database: POST /api/v1/database-clients/{client_id}/ingest?user_id={user_id}
  4. Pantau koneksi: GET /api/v1/database-clients/{user_id}

Setelah dokumen/database siap, frontend dapat rebuild dan membaca user data catalog:

  1. POST /api/v1/data-catalog/rebuild
  2. GET /api/v1/data-catalog/{user_id}

4. Membuat New Analysis

Frontend menampilkan form:

  • analysis_title
  • objective
  • business_questions
  • data_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:

  1. POST /api/v1/analyses dengan title, objective, business_questions, dan data_bind.
  2. Ambil data.id dari response sebagai analysis_id.
  3. Frontend memanggil AI Agent Service terpisah memakai context analysis, business_questions, dan catalog.
  4. Saat user mulai bertanya ke AI Agent Service, rekam pertanyaan dengan role=user ke endpoint messages.
  5. Setelah AI Agent Service menjawab, simpan jawaban dengan role=ai ke 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:

  1. Rekam pertanyaan user:
{
  "role": "user",
  "content": "Apa penyebab revenue turun di Q3?"
}
  1. 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 created
  • 200: 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_bind wajib berisi minimal satu source.
  • Semua source harus milik user yang sedang login.
  • Duplicate source dalam satu data_bind ditolak.

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_questions wajib berisi minimal satu string non-empty.
  • data_bind wajib 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 invalid
  • 401: token invalid/missing
  • 409: stale expected_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 user
  • ai: 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 ID
  • 401: token invalid/missing
  • 409: 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}/messages dengan 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_bind analysis.
  • Perubahan data_bind akan 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, gunakan data.user.id dari login dan pastikan sama dengan token aktif.
  • Untuk binding analysis, pakai source yang sudah berhasil diupload/diproses atau database client yang sudah diingest.