Browse Source

docs: buat struktur docapi AI-Friendly untuk geonet-console

- README.md, index.md, authentication.md, common-response.md, common-error.md, integration-guide.md
- services/auth/README.md + login.md
- services/service-tokens/README.md + create, show, list, revoke, regenerate, delete, by-service, active, expired
- services/databases/README.md
- services/ldap/README.md
- services/project-search/README.md

Dokumentasi mencakup: business rule, contoh request/response, sequence flow,
audit log, error guide, retry policy, SDK cURL/Python/Laravel, dampak ke GeoNetAgent.
master
Budi Setiawan 3 weeks ago
parent
commit
39fe810cba
  1. 72
      server-connection/geonet-console/docapi/README.md
  2. 107
      server-connection/geonet-console/docapi/authentication.md
  3. 116
      server-connection/geonet-console/docapi/common-error.md
  4. 90
      server-connection/geonet-console/docapi/common-response.md
  5. 79
      server-connection/geonet-console/docapi/index.md
  6. 145
      server-connection/geonet-console/docapi/integration-guide.md
  7. 48
      server-connection/geonet-console/docapi/services/auth/README.md
  8. 188
      server-connection/geonet-console/docapi/services/auth/login.md
  9. 41
      server-connection/geonet-console/docapi/services/databases/README.md
  10. 49
      server-connection/geonet-console/docapi/services/ldap/README.md
  11. 42
      server-connection/geonet-console/docapi/services/project-search/README.md
  12. 119
      server-connection/geonet-console/docapi/services/service-tokens/README.md
  13. 48
      server-connection/geonet-console/docapi/services/service-tokens/active.md
  14. 52
      server-connection/geonet-console/docapi/services/service-tokens/by-service.md
  15. 178
      server-connection/geonet-console/docapi/services/service-tokens/create.md
  16. 58
      server-connection/geonet-console/docapi/services/service-tokens/delete.md
  17. 48
      server-connection/geonet-console/docapi/services/service-tokens/expired.md
  18. 57
      server-connection/geonet-console/docapi/services/service-tokens/list.md
  19. 136
      server-connection/geonet-console/docapi/services/service-tokens/regenerate.md
  20. 90
      server-connection/geonet-console/docapi/services/service-tokens/revoke.md
  21. 66
      server-connection/geonet-console/docapi/services/service-tokens/show.md

72
server-connection/geonet-console/docapi/README.md

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
# docapi — API Documentation (geonet-console)
Folder ini adalah **Single Source of Truth** untuk seluruh dokumentasi API geonet-console.
AI Agent dan Developer **wajib** membaca folder ini sebelum menggunakan atau mengembangkan API.
Tidak perlu membuka source code, controller, atau database schema.
---
## Aturan
- Dokumentasi API adalah bagian dari source code.
- Implementasi tanpa dokumentasi dianggap **belum selesai**.
- Setiap perubahan API **wajib** diikuti perubahan dokumentasi di folder ini.
- Markdown menjelaskan business rule. OpenAPI (`api-docs/openapi.json`) menjelaskan spesifikasi teknis.
---
## Struktur
```
docapi/
README.md ← file ini
index.md ← daftar semua endpoint
authentication.md ← panduan autentikasi
common-response.md ← format response standar
common-error.md ← kode error standar
pagination.md ← konvensi paginasi
versioning.md ← kebijakan versi API
integration-guide.md ← panduan integrasi antar service
services/
auth/ ← login, token guide
service-tokens/ ← CRUD service tokens (microservice Bearer)
databases/ ← database registry
ldap/ ← LDAP users & groups
project-search/ ← Ollama NAS project search
```
---
## Base URL
| Environment | URL |
|-------------|-----|
| Production | `https://console.gisportal.id/api/v1` |
## Autentikasi
Lihat [`authentication.md`](./authentication.md) untuk panduan lengkap.
Ringkasan: semua endpoint (kecuali `/auth/login`) memerlukan header:
```
Authorization: Bearer <token>
```
Token diperoleh dari `POST /api/v1/auth/login` atau dari API Token yang diterbitkan di halaman `/api-clients`.
---
## Checklist AI Sebelum Membuat Endpoint Baru
- [ ] Endpoint dibuat di `routes/api.php`
- [ ] Controller method dibuat
- [ ] File markdown endpoint dibuat di `docapi/services/{service}/`
- [ ] `docapi/services/{service}/README.md` diperbarui
- [ ] `docapi/index.md` diperbarui
- [ ] Contoh request & response disertakan
- [ ] Error dijelaskan
- [ ] Business rule dijelaskan
- [ ] Audit log dicatat jika endpoint mengubah data

107
server-connection/geonet-console/docapi/authentication.md

@ -0,0 +1,107 @@ @@ -0,0 +1,107 @@
# Authentication — geonet-console API
geonet-console mendukung **3 metode autentikasi** untuk API.
---
## 1. LDAP JWT (untuk pengguna manusia / AI Agent interaktif)
Diperoleh dari `POST /api/v1/auth/login` menggunakan kredensial domain LDAP.
```
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "john.doe",
"password": "password123"
}
```
Response:
```json
{
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"auth_type": "ldap_jwt",
"user": {
"username": "john.doe",
"display_name": "John Doe",
"is_admin": true
}
}
}
```
Gunakan token pada setiap request:
```
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
```
**TTL:** Default 3600 detik (1 jam). Dikonfigurasi via `API_LDAP_JWT_TTL` di `.env`.
**Scope:** JWT dari admin LDAP memiliki akses penuh. JWT dari non-admin hanya akses terbatas.
---
## 2. API Token (untuk service-to-service, server-side automation)
Diterbitkan di halaman `/api-clients` oleh admin. Token tidak expire kecuali dihapus manual.
```
Authorization: Bearer geonet_<token_string>
```
Setiap API Token memiliki **scope** yang menentukan akses:
| Scope | Akses |
|-------|-------|
| `databases:read` | Baca daftar database |
| `databases:write` | Ubah status database |
| `ldap:read` | Baca user & group LDAP |
| `ldap:write` | Ubah user & group LDAP |
| `project-search:read` | Query project search |
---
## 3. Service Token (untuk microservice Bearer token — GeoNetAgent, dll.)
Diterbitkan di `/api-clients` → bagian **Service Tokens**.
Digunakan oleh microservice seperti GeoNetAgent untuk autentikasi ke collector.
```
Authorization: Bearer Col5FUFl34dVXgyBgTSA23KsYc5QhAh8s224OkR5GjQ
```
> **Catatan:** Service Token divalidasi oleh masing-masing microservice (bukan oleh geonet-console API). geonet-console hanya berfungsi sebagai registry dan management UI. Lihat [`services/service-tokens/README.md`](./services/service-tokens/README.md).
---
## Urutan Prioritas Autentikasi
```
Request masuk
Cek header: Authorization: Bearer <token>
Apakah JWT? (starts with eyJ)
→ Ya → Validasi JWT LDAP
→ Tidak → Cek API Token di database
→ Valid → Lanjut dengan scope token
→ Tidak valid → 401 Unauthorized
```
---
## Error Autentikasi
| Kode | Kondisi | Solusi |
|------|---------|--------|
| `401` | Token tidak ada / tidak valid | Login ulang atau cek token |
| `401` | JWT expired | Login ulang ke `POST /auth/login` |
| `403` | Token valid tapi scope tidak cukup | Minta admin tambah scope |
| `429` | Rate limit login (10x/menit) | Tunggu 1 menit |

116
server-connection/geonet-console/docapi/common-error.md

@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
# Error Guide — geonet-console API
Panduan lengkap untuk menangani error. AI Agent tidak boleh menebak — ikuti panduan ini.
---
## 401 Unauthorized
**Kondisi:** Token tidak ada, tidak valid, atau expired.
**Solusi:**
- JWT expired → Login ulang ke `POST /api/v1/auth/login`
- API Token salah → Cek token di `/api-clients`
- Header tidak ada → Pastikan format `Authorization: Bearer <token>`
**Contoh response:**
```json
{
"error": {
"code": "UNAUTHENTICATED",
"message": "Unauthenticated."
}
}
```
**Retry:** Tidak boleh retry dengan token yang sama. Harus dapatkan token baru.
---
## 403 Forbidden
**Kondisi:** Token valid tapi tidak memiliki scope yang diperlukan.
**Solusi:** Minta admin tambahkan scope yang diperlukan pada API Token di `/api-clients`.
**Contoh response:**
```json
{
"error": {
"code": "FORBIDDEN",
"message": "Insufficient scope. Required: ldap:write"
}
}
```
**Retry:** Tidak perlu retry. Masalah ada di permission, bukan token.
---
## 404 Not Found
**Kondisi:** Resource tidak ditemukan (ID salah, sudah dihapus).
**Contoh response:**
```json
{
"error": {
"code": "NOT_FOUND",
"message": "Service token not found"
}
}
```
**Retry:** Tidak perlu retry. Verifikasi ID yang digunakan.
---
## 422 Unprocessable Entity
**Kondisi:** Data request tidak lulus validasi.
**Contoh response:**
```json
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name field is required."],
"expires_in_days": ["The expires in days must be at least 1."]
}
}
```
**Retry:** Tidak perlu retry. Perbaiki data request sesuai pesan error.
---
## 429 Too Many Requests
**Kondisi:** Melebihi rate limit.
| Endpoint | Rate Limit |
|----------|------------|
| `POST /auth/login` | 10 request / menit |
| `POST /project-search/ask` | 20 request / menit |
**Contoh response:**
```json
{
"message": "Too Many Attempts."
}
```
**Retry:** Tunggu 60 detik sebelum retry. Cek header `Retry-After`.
---
## 500 Internal Server Error
**Kondisi:** Error di sisi server (bug, DB down, dll.).
**Solusi:**
1. Cek Laravel log: `docker exec geonet-console tail -100 storage/logs/laravel.log`
2. Cek container: `docker logs geonet-console --tail 50`
3. Jangan retry lebih dari 3x dengan exponential backoff.
**Retry policy:** Max 3x, backoff: 1s → 2s → 4s.

90
server-connection/geonet-console/docapi/common-response.md

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
# Format Response Standar
Semua response API geonet-console menggunakan format JSON konsisten.
---
## Response Sukses — Single Resource
```json
{
"data": {
"id": "uuid",
"field": "value"
}
}
```
## Response Sukses — Collection
```json
{
"data": [
{ "id": "uuid-1", "field": "value" },
{ "id": "uuid-2", "field": "value" }
]
}
```
## Response Sukses — Action (revoke, delete, dll.)
```json
{
"message": "Operasi berhasil."
}
```
## Response Sukses — Create (dengan token sekali tampil)
```json
{
"data": {
"id": "uuid",
"token": "plain_token_hanya_tampil_sekali",
"token_prefix": "Col5FUFl34dVXgyB"
},
"message": "Token created. Save it now — it will not be shown again."
}
```
---
## Response Error
```json
{
"error": {
"code": "ERROR_CODE",
"message": "Deskripsi error yang dapat dibaca manusia."
}
}
```
## Response Error — Validation
```json
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name field is required."],
"service": ["The service field is required."]
}
}
```
---
## HTTP Status Codes
| Code | Kondisi |
|------|---------|
| `200` | OK — request berhasil |
| `201` | Created — resource baru dibuat |
| `204` | No Content — delete berhasil |
| `400` | Bad Request — request tidak valid |
| `401` | Unauthorized — tidak ada / token invalid |
| `403` | Forbidden — token valid tapi tidak punya akses |
| `404` | Not Found — resource tidak ditemukan |
| `422` | Unprocessable Entity — validasi gagal |
| `429` | Too Many Requests — rate limit |
| `500` | Internal Server Error — error server |

79
server-connection/geonet-console/docapi/index.md

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
# API Endpoint Index — geonet-console
Base URL: `https://console.gisportal.id/api/v1`
---
## Auth
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| POST | `/auth/login` | — | — | Login LDAP, dapat JWT | [login.md](./services/auth/login.md) |
| GET | `/auth/token-guide` | — | — | Panduan penggunaan token | [token-guide.md](./services/auth/token-guide.md) |
---
## Me
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| GET | `/me` | JWT / API Token | — | Info user yang sedang login | [me.md](./services/auth/me.md) |
---
## Databases
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| GET | `/databases` | JWT / API Token | `databases:read` | List semua database | [index.md](./services/databases/list.md) |
| POST | `/databases/{database}/offline` | JWT / API Token | `databases:write` | Tandai database offline | [offline.md](./services/databases/offline.md) |
---
## LDAP Users
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| GET | `/ldap/users` | JWT / API Token | `ldap:read` | List semua user LDAP | [list.md](./services/ldap/users-list.md) |
| GET | `/ldap/users/{username}` | JWT / API Token | `ldap:read` | Detail user LDAP | [show.md](./services/ldap/users-show.md) |
| PUT | `/ldap/users/{username}` | JWT / API Token | `ldap:write` | Update user LDAP | [update.md](./services/ldap/users-update.md) |
| POST | `/ldap/users/{username}/groups` | JWT / API Token | `ldap:write` | Tambah user ke group | [add-group.md](./services/ldap/users-add-group.md) |
| DELETE | `/ldap/users/{username}/groups/{group}` | JWT / API Token | `ldap:write` | Hapus user dari group | [remove-group.md](./services/ldap/users-remove-group.md) |
---
## LDAP Groups
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| GET | `/ldap/groups` | JWT / API Token | `ldap:read` | List semua group | [list.md](./services/ldap/groups-list.md) |
| GET | `/ldap/groups/{group}` | JWT / API Token | `ldap:read` | Detail group | [show.md](./services/ldap/groups-show.md) |
| POST | `/ldap/groups` | JWT / API Token | `ldap:write` | Buat group baru | [create.md](./services/ldap/groups-create.md) |
| POST | `/ldap/groups/{group}/members` | JWT / API Token | `ldap:write` | Tambah member ke group | [add-member.md](./services/ldap/groups-add-member.md) |
| DELETE | `/ldap/groups/{group}/members/{username}` | JWT / API Token | `ldap:write` | Hapus member dari group | [remove-member.md](./services/ldap/groups-remove-member.md) |
---
## Service Tokens
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| GET | `/service-tokens` | JWT / API Token | — | List semua service tokens | [list.md](./services/service-tokens/list.md) |
| POST | `/service-tokens` | JWT / API Token | — | Buat service token baru | [create.md](./services/service-tokens/create.md) |
| GET | `/service-tokens/{id}` | JWT / API Token | — | Detail service token | [show.md](./services/service-tokens/show.md) |
| POST | `/service-tokens/{id}/revoke` | JWT / API Token | — | Revoke service token | [revoke.md](./services/service-tokens/revoke.md) |
| POST | `/service-tokens/{id}/regenerate` | JWT / API Token | — | Regenerate service token | [regenerate.md](./services/service-tokens/regenerate.md) |
| DELETE | `/service-tokens/{id}` | JWT / API Token | — | Hapus service token | [delete.md](./services/service-tokens/delete.md) |
| GET | `/service-tokens/by-service/{service}` | JWT / API Token | — | Token by nama service | [by-service.md](./services/service-tokens/by-service.md) |
| GET | `/service-tokens/active` | JWT / API Token | — | Semua token aktif | [active.md](./services/service-tokens/active.md) |
| GET | `/service-tokens/expired` | JWT / API Token | — | Semua token expired | [expired.md](./services/service-tokens/expired.md) |
---
## Project Search
| Method | Endpoint | Auth | Scope | Deskripsi | Dokumen |
|--------|----------|------|-------|-----------|---------|
| GET | `/project-search/sources` | JWT / API Token | `project-search:read` | Daftar sumber data | [sources.md](./services/project-search/sources.md) |
| GET | `/project-search/index/status` | JWT / API Token | `project-search:read` | Status indeks per source | [index-status.md](./services/project-search/index-status.md) |
| POST | `/project-search/ask` | JWT / API Token | `project-search:read` | Query natural language | [ask.md](./services/project-search/ask.md) |

145
server-connection/geonet-console/docapi/integration-guide.md

@ -0,0 +1,145 @@ @@ -0,0 +1,145 @@
# Integration Guide — geonet-console API
Panduan integrasi untuk AI Agent dan microservice yang menggunakan geonet-console API.
---
## Alur Integrasi untuk AI Agent (JWT)
```
Langkah 1: Login
POST /api/v1/auth/login
Langkah 2: Simpan access_token
Langkah 3: Gunakan token pada setiap request
Authorization: Bearer <access_token>
Langkah 4: Jika response 401 → Login ulang
Langkah 5: Jika response 403 → Token tidak punya scope yang cukup
```
---
## Alur Integrasi untuk Microservice (API Token / Service Token)
```
Langkah 1: Admin buat API Token atau Service Token di /api-clients
Langkah 2: Simpan token di .env atau config microservice
Langkah 3: Gunakan pada setiap request
Authorization: Bearer <token>
Langkah 4: Token tidak expire kecuali dihapus/direvoke manual
```
---
## Dependency Antar Service
```
geonet-console
↓ membaca
LDAP (Active Directory) — 10.100.1.40
↓ membaca/menulis
PostgreSQL App DB (databaselist_app) — 10.100.1.24 (Docker)
↓ menulis audit
PostgreSQL Audit DB (databaselist_audit) — 10.100.1.24 (Docker)
↓ sinkronisasi service tokens
PostgreSQL GeoNetAgent DB (geonetagent_dev) — 10.100.1.25
↓ query project search
PostgreSQL Project Search DB (geonet_project_search) — 10.100.1.25
↓ inference
Ollama (VM aiopr) — 10.100.1.26
```
---
## GeoNetAgent Integration
GeoNetAgent menggunakan **Service Token** untuk autentikasi ke collector.
Token dikelola di geonet-console `/api-clients`**Service Tokens**.
Saat token dibuat/regenerate di UI, token otomatis disinkronkan ke `geonetagent_dev.agent_tokens`.
```
Admin buat Service Token di geonet-console
↓ sinkron otomatis
geonetagent_dev.agent_tokens (via AgentTokenSyncService)
GeoNetAgent Agent (PowerShell) baca config.json
POST https://agent.gisportal.id/api/v1/agent/report
Authorization: Bearer <service_token>
Collector (FastAPI) validasi token dari agent_tokens
200 OK / 401 Unauthorized
```
**File config agent:** `GeoNetAgent/agent/config.json`
```json
{
"collector_url": "https://agent.gisportal.id/api/v1/agent/report",
"agent_token": "<service_token_lengkap>"
}
```
---
## Contoh SDK
### cURL (wajib)
```bash
# Login
curl -s -X POST https://console.gisportal.id/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"john.doe","password":"password123"}'
# List databases (dengan JWT)
curl -s https://console.gisportal.id/api/v1/databases \
-H "Authorization: Bearer <jwt_token>"
# List service tokens (dengan API Token)
curl -s https://console.gisportal.id/api/v1/service-tokens \
-H "Authorization: Bearer <api_token>"
```
### Python
```python
import requests
BASE_URL = "https://console.gisportal.id/api/v1"
# Login
resp = requests.post(f"{BASE_URL}/auth/login", json={
"username": "john.doe",
"password": "password123"
})
token = resp.json()["data"]["access_token"]
# Gunakan token
headers = {"Authorization": f"Bearer {token}"}
databases = requests.get(f"{BASE_URL}/databases", headers=headers).json()
```
### Laravel (PHP)
```php
use Illuminate\Support\Facades\Http;
$response = Http::post('https://console.gisportal.id/api/v1/auth/login', [
'username' => 'john.doe',
'password' => 'password123',
]);
$token = $response->json('data.access_token');
$databases = Http::withToken($token)
->get('https://console.gisportal.id/api/v1/databases')
->json();
```

48
server-connection/geonet-console/docapi/services/auth/README.md

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
# Auth Service
## Deskripsi
Menyediakan autentikasi berbasis LDAP dengan JWT token untuk akses API geonet-console.
## Tanggung Jawab
- Login via kredensial LDAP domain (Active Directory)
- Menerbitkan JWT token dengan TTL terkonfigurasi
- Menyediakan panduan penggunaan token
## Dependency
- Active Directory LDAP: `10.100.1.40:389`
- `LdapAuthService` — validasi kredensial
- `LdapJwtService` — penerbitan dan validasi JWT
## URL Service
`https://console.gisportal.id/api/v1/auth`
## Authentication
Endpoint login dan token-guide **tidak memerlukan autentikasi**.
## Endpoint
| Method | Path | Deskripsi | Dokumen |
|--------|------|-----------|---------|
| POST | `/auth/login` | Login LDAP, dapat JWT | [login.md](./login.md) |
| GET | `/auth/token-guide` | Panduan token | [token-guide.md](./token-guide.md) |
| GET | `/me` | Info user aktif | [me.md](./me.md) |
## Database
- Tidak menulis ke database (autentikasi murni via LDAP)
- Audit log ditulis ke `databaselist_audit` via `AuditLogService`
## Rate Limit
- `POST /auth/login`: 10 request/menit per IP
## Service yang Memanggil
- Browser UI (form login)
- AI Agent (automation login)
- Microservice yang butuh JWT untuk API call

188
server-connection/geonet-console/docapi/services/auth/login.md

@ -0,0 +1,188 @@ @@ -0,0 +1,188 @@
# Login
## Tujuan
Autentikasi pengguna via LDAP dan mendapatkan JWT Bearer token untuk mengakses API.
## Business Rule
- Username dan password divalidasi ke Active Directory (`10.100.1.40`)
- Hanya user yang terdaftar di group `Domain Admins`, `Administrators`, atau `Enterprise Admins` yang mendapat `is_admin: true`
- JWT diterbitkan dengan TTL dari `API_LDAP_JWT_TTL` (default: 3600 detik)
- Setiap percobaan login (berhasil maupun gagal) dicatat di audit log
- Maksimum 10 percobaan login per menit per IP
## URL
`POST https://console.gisportal.id/api/v1/auth/login`
## HTTP Method
`POST`
## Authentication
Tidak diperlukan.
## Request Header
```
Content-Type: application/json
```
## Request Body
```json
{
"username": "john.doe",
"password": "Password123!"
}
```
## Validation
| Field | Aturan |
|-------|--------|
| `username` | required, string, max 100 karakter |
| `password` | required, string, max 255 karakter |
## Response Success
**HTTP 200**
```json
{
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huLmRvZSIsImlzX2FkbWluIjp0cnVlLCJleHAiOjE3MTk1MDAwMDB9.signature",
"token_type": "Bearer",
"expires_in": 3600,
"auth_type": "ldap_jwt",
"user": {
"username": "john.doe",
"display_name": "John Doe",
"is_admin": true
}
}
}
```
## Response Error
**HTTP 401 — Kredensial salah:**
```json
{
"error": {
"code": "invalid_credentials",
"message": "Invalid LDAP credentials."
}
}
```
**HTTP 422 — Validasi gagal:**
```json
{
"message": "The given data was invalid.",
"errors": {
"username": ["The username field is required."]
}
}
```
**HTTP 429 — Rate limit:**
```json
{
"message": "Too Many Attempts."
}
```
## Status Code
| Code | Kondisi |
|------|---------|
| 200 | Login berhasil |
| 401 | Kredensial LDAP salah |
| 422 | Validasi request gagal |
| 429 | Rate limit (10x/menit) |
## Contoh Request
```bash
curl -s -X POST https://console.gisportal.id/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"john.doe","password":"Password123!"}'
```
## Contoh Response
```json
{
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"auth_type": "ldap_jwt",
"user": {
"username": "john.doe",
"display_name": "John Doe",
"is_admin": true
}
}
}
```
## Sequence Flow
```mermaid
sequenceDiagram
Client->>API: POST /auth/login {username, password}
API->>LDAP: bind(username, password)
LDAP-->>API: success / failed
alt Login berhasil
API->>LDAP: lookup user groups
LDAP-->>API: group list
API->>API: issue JWT
API->>AuditLog: log api.v1.auth.login
API-->>Client: 200 {access_token, user}
else Login gagal
API->>AuditLog: log api.v1.auth.login.failed
API-->>Client: 401 invalid_credentials
end
```
## Database yang Diakses
- LDAP (`10.100.1.40`) — read only untuk validasi
- `databaselist_audit` — write untuk audit log
## Audit Log
| Event | Kondisi |
|-------|---------|
| `api.v1.auth.login` | Login berhasil |
| `api.v1.auth.login.failed` | Login gagal |
## Rate Limit
10 request / menit per IP. Dikonfigurasi via Laravel throttle middleware `throttle:10,1`.
## Idempotent
Tidak — setiap request login menghasilkan JWT baru.
## Retry Policy
- Jika `401`: jangan retry otomatis. Minta user input ulang.
- Jika `429`: tunggu 60 detik.
- Jika `500`: retry max 2x dengan backoff 2s.
## Security
- Password tidak disimpan di geonet-console, divalidasi langsung ke LDAP
- JWT disign dengan `APP_KEY` Laravel
- Token dikirim hanya via HTTPS
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Dokumentasi dibuat |

41
server-connection/geonet-console/docapi/services/databases/README.md

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
# Databases Service
## Deskripsi
Registry dan monitoring database yang terdaftar di geonet-console (eks. databaselist).
## Endpoint
| Method | Path | Scope | Deskripsi |
|--------|------|-------|-----------|
| GET | `/databases` | `databases:read` | List semua database |
| POST | `/databases/{database}/offline` | `databases:write` | Tandai database offline |
## Authentication
```
Authorization: Bearer <jwt_atau_api_token_dengan_scope_databases:read>
```
## Contoh Request
```bash
# List databases
curl -s https://console.gisportal.id/api/v1/databases \
-H "Authorization: Bearer <token>"
# Tandai offline
curl -s -X POST \
https://console.gisportal.id/api/v1/databases/my-database/offline \
-H "Authorization: Bearer <token>"
```
## Database yang Digunakan
- `databaselist_app` — tabel databases
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | README dibuat |

49
server-connection/geonet-console/docapi/services/ldap/README.md

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
# LDAP Service
## Deskripsi
Manajemen user dan group Active Directory via LDAP. Read dan write ke domain `gisportal.id`.
## Dependency
- LDAP Server: `10.100.1.40:389`
- Domain: `DC=gisportal,DC=id`
- Service account: `Administrator@gisportal.id`
## Endpoint Users
| Method | Path | Scope | Deskripsi |
|--------|------|-------|-----------|
| GET | `/ldap/users` | `ldap:read` | List semua user |
| GET | `/ldap/users/{username}` | `ldap:read` | Detail user |
| PUT | `/ldap/users/{username}` | `ldap:write` | Update user |
| POST | `/ldap/users/{username}/groups` | `ldap:write` | Tambah ke group |
| DELETE | `/ldap/users/{username}/groups/{group}` | `ldap:write` | Hapus dari group |
## Endpoint Groups
| Method | Path | Scope | Deskripsi |
|--------|------|-------|-----------|
| GET | `/ldap/groups` | `ldap:read` | List semua group |
| GET | `/ldap/groups/{group}` | `ldap:read` | Detail group |
| POST | `/ldap/groups` | `ldap:write` | Buat group baru |
| POST | `/ldap/groups/{group}/members` | `ldap:write` | Tambah member |
| DELETE | `/ldap/groups/{group}/members/{username}` | `ldap:write` | Hapus member |
## Contoh Request
```bash
# List users
curl -s https://console.gisportal.id/api/v1/ldap/users \
-H "Authorization: Bearer <token_dengan_scope_ldap:read>"
# List groups
curl -s https://console.gisportal.id/api/v1/ldap/groups \
-H "Authorization: Bearer <token>"
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | README dibuat |

42
server-connection/geonet-console/docapi/services/project-search/README.md

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
# Project Search Service
## Deskripsi
Natural language search untuk file project di NAS via Ollama (LLM) dan PostgreSQL vector index.
**Status:** Diimplementasi sebagian. Endpoint tersedia tapi index NAS belum aktif di production.
## Dependency
- Ollama: `http://10.100.1.26:11434` (VM aiopr)
- Model chat: `qwen2.5:7b`
- Model embed: `nomic-embed-text`
- PostgreSQL Project Search: `geonet_project_search` (10.100.1.25)
## Endpoint
| Method | Path | Scope | Deskripsi |
|--------|------|-------|-----------|
| GET | `/project-search/sources` | `project-search:read` | Daftar sumber data |
| GET | `/project-search/index/status` | `project-search:read` | Status indeks per source |
| POST | `/project-search/ask` | `project-search:read` | Query natural language |
## Rate Limit
`POST /project-search/ask`: 20 request / menit
## Contoh Request
```bash
# Query
curl -s -X POST https://console.gisportal.id/api/v1/project-search/ask \
-H "Authorization: Bearer <token_dengan_scope_project-search:read>" \
-H "Content-Type: application/json" \
-d '{"query": "Laporan survey jalan tol 2025", "sources": ["project"]}'
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | README dibuat |

119
server-connection/geonet-console/docapi/services/service-tokens/README.md

@ -0,0 +1,119 @@ @@ -0,0 +1,119 @@
# Service Tokens
## Deskripsi
Centralized management untuk Bearer token yang digunakan oleh microservice (GeoNetAgent, dll.).
Service Tokens adalah token sederhana berbasis SHA256 hash yang dikelola di geonet-console
sebagai single point of control, dengan sinkronisasi otomatis ke database microservice terkait.
## Tanggung Jawab
- Menerbitkan Bearer token baru untuk microservice
- Menyimpan hash token (plain text tidak pernah disimpan)
- Menyinkronkan token ke `geonetagent_dev.agent_tokens` via `AgentTokenSyncService`
- Revoke dan hapus token dengan sinkronisasi ke database microservice
- Mencatat seluruh aksi ke audit log
## Dependency
- `ServiceTokenService` — logika CRUD + audit
- `AgentTokenSyncService` — push ke `geonetagent_dev.agent_tokens`
- `AuditLogService` — audit trail
- PostgreSQL `databaselist_app` — tabel `service_tokens`
- PostgreSQL `geonetagent_dev` (10.100.1.25) — tabel `agent_tokens` (sync target)
## URL Service
`https://console.gisportal.id/api/v1/service-tokens`
## Authentication
Semua endpoint memerlukan autentikasi:
```
Authorization: Bearer <jwt_token_atau_api_token>
```
## Endpoint
| Method | Path | Deskripsi | Dokumen |
|--------|------|-----------|---------|
| GET | `/service-tokens` | List semua token | [list.md](./list.md) |
| POST | `/service-tokens` | Buat token baru | [create.md](./create.md) |
| GET | `/service-tokens/{id}` | Detail token | [show.md](./show.md) |
| POST | `/service-tokens/{id}/revoke` | Revoke token | [revoke.md](./revoke.md) |
| POST | `/service-tokens/{id}/regenerate` | Regenerate token | [regenerate.md](./regenerate.md) |
| DELETE | `/service-tokens/{id}` | Hapus permanen | [delete.md](./delete.md) |
| GET | `/service-tokens/by-service/{service}` | Filter by service | [by-service.md](./by-service.md) |
| GET | `/service-tokens/active` | Hanya token aktif | [active.md](./active.md) |
| GET | `/service-tokens/expired` | Hanya token expired | [expired.md](./expired.md) |
## Database yang Digunakan
### `service_tokens` (databaselist_app)
| Kolom | Tipe | Keterangan |
|-------|------|------------|
| `id` | UUID | Primary key |
| `name` | varchar(100) | Nama token (e.g. "GeoNetAgent-Production") |
| `service` | varchar(50) | Nama service (e.g. "GeoNetAgent") |
| `token_prefix` | varchar(20) | 16 char pertama token (display only) |
| `token_hash` | varchar(64) | SHA256 hash token lengkap |
| `is_active` | boolean | Status aktif |
| `expires_at` | timestamptz | Waktu expiry (null = tidak pernah expire) |
| `created_by` | varchar(100) | Username yang membuat |
| `created_at` | timestamptz | Waktu dibuat |
| `last_used_at` | timestamptz | Terakhir digunakan (nullable) |
### `agent_tokens` (geonetagent_dev — sync target)
| Kolom | Tipe | Keterangan |
|-------|------|------------|
| `id` | UUID | Primary key |
| `name` | varchar(100) | Nama token |
| `token_hash` | varchar(128) | SHA256 hash |
| `is_active` | boolean | Status aktif |
| `last_used_at` | timestamptz | Terakhir digunakan |
| `created_at` | timestamptz | Waktu dibuat |
## Sinkronisasi ke GeoNetAgent
Saat token dibuat, direvoke, atau dihapus di geonet-console:
```
geonet-console (ServiceTokenService)
↓ via AgentTokenSyncService
↓ DB connection: geonetagent (config/database.php)
↓ user: geonet_portal (INSERT, SELECT, UPDATE, DELETE)
geonetagent_dev.agent_tokens
GeoNetAgent Collector (FastAPI) — validasi token incoming
```
**Fallback:** Jika `GEONETAGENT_DB_USERNAME` kosong di `.env`, sync di-skip dengan warning log. geonet-console tetap berjalan normal.
## Token Security
- Token plain text **hanya ditampilkan sekali** saat dibuat atau di-regenerate
- Database hanya menyimpan SHA256 hash — tidak reversible
- `token_prefix` (16 char pertama) digunakan untuk identifikasi di UI
- Jika token hilang → gunakan **Regenerate**
## Audit Log
| Event | Kondisi |
|-------|---------|
| `service_token_created` | Token baru dibuat |
| `service_token_revoked` | Token direvoke |
| `service_token_regenerated` | Token di-regenerate |
| `service_token_deleted` | Token dihapus permanen |
## Service yang Memanggil
- Admin via UI `/api-clients`
- AI Agent via API `POST /api/v1/service-tokens`
## Service yang Dipanggil
- `geonetagent_dev` PostgreSQL (sinkronisasi)
- `databaselist_audit` PostgreSQL (audit log)

48
server-connection/geonet-console/docapi/services/service-tokens/active.md

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
# Get Active Tokens
## Tujuan
Mendapatkan semua service token yang aktif dan belum expired.
## URL
`GET https://console.gisportal.id/api/v1/service-tokens/active`
## HTTP Method
`GET`
## Response Success
**HTTP 200**
```json
{
"data": [
{
"id": "065eb796-ecb5-4d95-b4cd-9ca6244cf13f",
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Col5FUFl34dVXgyB",
"is_active": true,
"expires_at": null,
"created_by": "admin",
"created_at": "2026-06-23T08:54:04+07:00",
"last_used_at": null
}
]
}
```
## Contoh Request
```bash
curl -s https://console.gisportal.id/api/v1/service-tokens/active \
-H "Authorization: Bearer <jwt_token>"
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

52
server-connection/geonet-console/docapi/services/service-tokens/by-service.md

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
# Get Tokens by Service
## Tujuan
Filter semua token berdasarkan nama service.
## URL
`GET https://console.gisportal.id/api/v1/service-tokens/by-service/{service}`
## Request Parameter
| Parameter | Tipe | Keterangan |
|-----------|------|------------|
| `service` | string | Nama service (case-sensitive, e.g. "GeoNetAgent") |
## Response Success
**HTTP 200**
```json
{
"data": [
{
"id": "065eb796-ecb5-4d95-b4cd-9ca6244cf13f",
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Col5FUFl34dVXgyB",
"is_active": true,
"expires_at": null,
"created_by": "admin",
"created_at": "2026-06-23T08:54:04+07:00",
"last_used_at": null,
"is_expired": false
}
]
}
```
## Contoh Request
```bash
curl -s \
"https://console.gisportal.id/api/v1/service-tokens/by-service/GeoNetAgent" \
-H "Authorization: Bearer <jwt_token>"
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

178
server-connection/geonet-console/docapi/services/service-tokens/create.md

@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
# Create Service Token
## Tujuan
Membuat Bearer token baru untuk microservice. Token plain text ditampilkan **sekali** — harus disimpan saat itu juga.
## Business Rule
- Token dihasilkan secara acak (cryptographically secure random)
- 16 karakter pertama disimpan sebagai `token_prefix` untuk identifikasi UI
- SHA256 hash dari token lengkap disimpan di database (plain text tidak pernah disimpan)
- Token otomatis disinkronkan ke `geonetagent_dev.agent_tokens` jika `GEONETAGENT_DB_USERNAME` di-set
- Setelah endpoint ini mengembalikan response, token plain text tidak bisa diambil lagi
- Jika token hilang → gunakan endpoint Regenerate
## URL
`POST https://console.gisportal.id/api/v1/service-tokens`
## HTTP Method
`POST`
## Authentication
```
Authorization: Bearer <jwt_token_atau_api_token>
```
## Request Header
```
Content-Type: application/json
Authorization: Bearer <token>
```
## Request Body
```json
{
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"expires_in_days": null
}
```
## Validation
| Field | Aturan |
|-------|--------|
| `name` | required, string, max 100 karakter |
| `service` | required, string, max 50 karakter |
| `expires_in_days` | nullable, integer, min 1 |
## Response Success
**HTTP 201**
```json
{
"data": {
"id": "065eb796-ecb5-4d95-b4cd-9ca6244cf13f",
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Col5FUFl34dVXgyB",
"token": "Col5FUFl34dVXgyBgTSA23KsYc5QhAh8s224OkR5GjQ",
"is_active": true,
"expires_at": null,
"created_by": "admin",
"created_at": "2026-06-23T08:54:04+07:00"
},
"message": "Service token created successfully. Save the token securely as it will not be shown again."
}
```
> **PENTING:** Field `token` hanya ada di response ini. Setelah request ini selesai, token tidak bisa diambil lagi.
## Response Error
**HTTP 422 — Validasi gagal:**
```json
{
"message": "The given data was invalid.",
"errors": {
"name": ["The name field is required."],
"service": ["The service field is required."]
}
}
```
**HTTP 401 — Tidak terautentikasi:**
```json
{
"error": {
"code": "UNAUTHENTICATED",
"message": "Unauthenticated."
}
}
```
## Status Code
| Code | Kondisi |
|------|---------|
| 201 | Token berhasil dibuat |
| 401 | Tidak terautentikasi |
| 422 | Validasi request gagal |
## Contoh Request
```bash
curl -s -X POST https://console.gisportal.id/api/v1/service-tokens \
-H "Authorization: Bearer <jwt_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"expires_in_days": null
}'
```
## Sequence Flow
```mermaid
sequenceDiagram
Client->>API: POST /service-tokens {name, service}
API->>API: Generate random token
API->>API: Hash token (SHA256)
API->>DB(databaselist_app): INSERT service_tokens
API->>DB(geonetagent_dev): INSERT agent_tokens (sync)
API->>AuditLog: log service_token_created
API-->>Client: 201 {token (plain, sekali tampil), prefix, id}
```
## Database yang Diakses
- `databaselist_app.service_tokens` — INSERT
- `geonetagent_dev.agent_tokens` — INSERT (sync, opsional)
- `databaselist_audit` — INSERT audit log
## Audit Log
Event: `service_token_created`
```json
{
"action": "service_token_created",
"entity_type": "ServiceToken",
"entity_id": "065eb796-ecb5-4d95-b4cd-9ca6244cf13f",
"details": {
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Col5FUFl34dVXgyB",
"expires_at": null,
"agent_token_synced": true
}
}
```
## Security
- Token hanya ditampilkan sekali — simpan segera
- Gunakan HTTPS — token tidak boleh dikirim via plain HTTP
- Simpan token di `.env` atau secret manager, bukan di source code
## Idempotent
Tidak — setiap request menghasilkan token baru yang berbeda.
## Retry Policy
- Jika `201` sudah diterima tapi token tidak sempat disimpan → jangan retry, gunakan Regenerate
- Jika `500`: retry max 1x. Cek apakah token sudah terbuat di database sebelum retry
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat, sync ke geonetagent_dev diimplementasi |

58
server-connection/geonet-console/docapi/services/service-tokens/delete.md

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
# Delete Service Token
## Tujuan
Menghapus service token secara permanen dari database. Tidak bisa di-undo.
## Business Rule
- Record dihapus dari `service_tokens` (hard delete)
- Record dihapus dari `geonetagent_dev.agent_tokens` (sync)
- Gunakan **Revoke** jika ingin menonaktifkan tapi tetap menyimpan audit trail
- Gunakan **Delete** hanya jika token sudah tidak relevan sama sekali
## URL
`DELETE https://console.gisportal.id/api/v1/service-tokens/{id}`
## HTTP Method
`DELETE`
## Request Parameter
| Parameter | Tipe | Keterangan |
|-----------|------|------------|
| `id` | UUID | ID service token |
## Response Success
**HTTP 200**
```json
{
"message": "Service token deleted successfully"
}
```
## Contoh Request
```bash
curl -s -X DELETE \
https://console.gisportal.id/api/v1/service-tokens/065eb796-ecb5-4d95-b4cd-9ca6244cf13f \
-H "Authorization: Bearer <jwt_token>"
```
## Audit Log
Event: `service_token_deleted`
## Idempotent
Tidak — menghapus ID yang tidak ada mengembalikan 404.
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

48
server-connection/geonet-console/docapi/services/service-tokens/expired.md

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
# Get Expired Tokens
## Tujuan
Mendapatkan semua service token yang sudah melewati `expires_at`.
## URL
`GET https://console.gisportal.id/api/v1/service-tokens/expired`
## HTTP Method
`GET`
## Response Success
**HTTP 200**
```json
{
"data": [
{
"id": "aabbccdd-1234-5678-abcd-ef1234567890",
"name": "OldToken-Staging",
"service": "GeoNetAgent",
"token_prefix": "AbCdEfGh12345678",
"is_active": false,
"expires_at": "2026-01-01T00:00:00+07:00",
"created_by": "admin",
"created_at": "2025-12-01T09:00:00+07:00",
"last_used_at": "2025-12-31T23:59:00+07:00"
}
]
}
```
## Contoh Request
```bash
curl -s https://console.gisportal.id/api/v1/service-tokens/expired \
-H "Authorization: Bearer <jwt_token>"
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

57
server-connection/geonet-console/docapi/services/service-tokens/list.md

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
# List Service Tokens
## Tujuan
Mendapatkan daftar semua service tokens (aktif, revoked, dan expired).
## URL
`GET https://console.gisportal.id/api/v1/service-tokens`
## HTTP Method
`GET`
## Authentication
```
Authorization: Bearer <jwt_token_atau_api_token>
```
## Response Success
**HTTP 200**
```json
{
"data": [
{
"id": "065eb796-ecb5-4d95-b4cd-9ca6244cf13f",
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Col5FUFl34dVXgyB",
"is_active": true,
"expires_at": null,
"created_by": "admin",
"created_at": "2026-06-23T08:54:04+07:00",
"last_used_at": null,
"is_expired": false
}
]
}
```
> **Catatan:** Field `token` (plain text) **tidak tersedia** di endpoint ini. Token plain hanya tersedia saat create/regenerate.
## Contoh Request
```bash
curl -s https://console.gisportal.id/api/v1/service-tokens \
-H "Authorization: Bearer <jwt_token>"
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

136
server-connection/geonet-console/docapi/services/service-tokens/regenerate.md

@ -0,0 +1,136 @@ @@ -0,0 +1,136 @@
# Regenerate Service Token
## Tujuan
Membuat token baru untuk service token yang sudah ada. Token lama langsung direvoke. Digunakan saat token hilang, bocor, atau perlu dirotasi.
## Business Rule
- Token lama direvoke terlebih dahulu (is_active = false)
- Token baru dibuat dengan name dan service yang sama
- Token baru disinkronkan ke `geonetagent_dev.agent_tokens`
- Token lama di-revoke di `geonetagent_dev.agent_tokens`
- **Downtime window:** antara revoke token lama dan distribusi token baru ke microservice
- Token plain text ditampilkan **sekali** — harus disimpan saat itu juga
## URL
`POST https://console.gisportal.id/api/v1/service-tokens/{id}/regenerate`
## HTTP Method
`POST`
## Authentication
```
Authorization: Bearer <jwt_token_atau_api_token>
```
## Request Parameter
| Parameter | Tipe | Keterangan |
|-----------|------|------------|
| `id` | UUID | ID service token yang akan di-regenerate |
## Request Body (opsional)
```json
{
"expires_in_days": 90
}
```
Jika tidak disertakan, token baru tidak expire (null).
## Response Success
**HTTP 200**
```json
{
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Xk9mPqR2nLvWsJhY",
"token": "Xk9mPqR2nLvWsJhYaB7cDeFgHiJkLmNoPqRsTuVwXyZ",
"is_active": true,
"expires_at": null,
"created_by": "admin",
"created_at": "2026-06-23T10:00:00+07:00"
},
"message": "Service token regenerated successfully. Save the new token securely as it will not be shown again."
}
```
## Response Error
**HTTP 404:**
```json
{
"error": {
"code": "NOT_FOUND",
"message": "Service token not found"
}
}
```
## Status Code
| Code | Kondisi |
|------|---------|
| 200 | Token berhasil di-regenerate |
| 401 | Tidak terautentikasi |
| 404 | Token ID tidak ditemukan |
## Contoh Request
```bash
curl -s -X POST \
https://console.gisportal.id/api/v1/service-tokens/065eb796-ecb5-4d95-b4cd-9ca6244cf13f/regenerate \
-H "Authorization: Bearer <jwt_token>" \
-H "Content-Type: application/json"
```
## Sequence Flow
```mermaid
sequenceDiagram
Client->>API: POST /service-tokens/{id}/regenerate
API->>DB(databaselist_app): Ambil token lama
API->>DB(databaselist_app): Revoke token lama (is_active=false)
API->>DB(geonetagent_dev): Revoke di agent_tokens (sync)
API->>API: Generate token baru
API->>DB(databaselist_app): INSERT service_tokens baru
API->>DB(geonetagent_dev): INSERT agent_tokens baru (sync)
API->>AuditLog: log service_token_regenerated
API-->>Client: 200 {token_baru (sekali tampil)}
```
## Dampak ke Microservice GeoNetAgent
Setelah regenerate, agent yang masih menggunakan token lama akan mendapat **401** dari collector.
**Langkah yang diperlukan:**
1. Copy token baru dari response
2. Update `config.json` di semua PC client agent:
```json
{ "agent_token": "<token_baru>" }
```
3. Distribusikan via GPO atau manual
4. Agent akan menggunakan token baru pada posting berikutnya
## Audit Log
Event: `service_token_regenerated`
## Idempotent
Tidak — setiap regenerate menghasilkan token baru.
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

90
server-connection/geonet-console/docapi/services/service-tokens/revoke.md

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
# Revoke Service Token
## Tujuan
Menonaktifkan service token tanpa menghapusnya. Token yang direvoke tetap tercatat di database untuk audit trail.
## Business Rule
- `is_active` diset ke `false`
- Token yang direvoke tidak bisa digunakan oleh microservice
- Sinkronisasi ke `geonetagent_dev.agent_tokens``is_active = false`
- Token masih dapat dilihat di daftar (dengan status "Revoked")
- Untuk menghapus permanen gunakan endpoint Delete
## URL
`POST https://console.gisportal.id/api/v1/service-tokens/{id}/revoke`
## HTTP Method
`POST`
## Authentication
```
Authorization: Bearer <jwt_token_atau_api_token>
```
## Request Parameter
| Parameter | Tipe | Keterangan |
|-----------|------|------------|
| `id` | UUID | ID service token |
## Response Success
**HTTP 200**
```json
{
"message": "Service token revoked successfully"
}
```
## Response Error
**HTTP 404:**
```json
{
"error": {
"code": "NOT_FOUND",
"message": "Service token not found"
}
}
```
## Status Code
| Code | Kondisi |
|------|---------|
| 200 | Token berhasil direvoke |
| 401 | Tidak terautentikasi |
| 404 | Token ID tidak ditemukan |
## Contoh Request
```bash
curl -s -X POST \
https://console.gisportal.id/api/v1/service-tokens/065eb796-ecb5-4d95-b4cd-9ca6244cf13f/revoke \
-H "Authorization: Bearer <jwt_token>"
```
## Dampak Langsung
- GeoNetAgent yang menggunakan token ini akan mendapat **401** dari collector pada posting berikutnya
- Tidak ada cara undo revoke — gunakan Regenerate untuk buat token baru
## Audit Log
Event: `service_token_revoked`
## Idempotent
Ya — merevoke token yang sudah direvoke tidak menghasilkan error.
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |

66
server-connection/geonet-console/docapi/services/service-tokens/show.md

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
# Get Service Token Detail
## Tujuan
Mendapatkan detail satu service token berdasarkan ID.
## URL
`GET https://console.gisportal.id/api/v1/service-tokens/{id}`
## HTTP Method
`GET`
## Request Parameter
| Parameter | Tipe | Keterangan |
|-----------|------|------------|
| `id` | UUID | ID service token |
## Response Success
**HTTP 200**
```json
{
"data": {
"id": "065eb796-ecb5-4d95-b4cd-9ca6244cf13f",
"name": "GeoNetAgent-Production",
"service": "GeoNetAgent",
"token_prefix": "Col5FUFl34dVXgyB",
"is_active": true,
"expires_at": null,
"created_by": "admin",
"created_at": "2026-06-23T08:54:04+07:00",
"last_used_at": null,
"is_expired": false
}
}
```
## Response Error
**HTTP 404:**
```json
{
"error": {
"code": "NOT_FOUND",
"message": "Service token not found"
}
}
```
## Contoh Request
```bash
curl -s \
https://console.gisportal.id/api/v1/service-tokens/065eb796-ecb5-4d95-b4cd-9ca6244cf13f \
-H "Authorization: Bearer <jwt_token>"
```
## Changelog
| Tanggal | Perubahan |
|---------|-----------|
| 2026-06-23 | Endpoint dibuat |
Loading…
Cancel
Save