|
|
|
|
@ -0,0 +1,351 @@
@@ -0,0 +1,351 @@
|
|
|
|
|
# Context Index (AI Entry Point) — geonet-console |
|
|
|
|
|
|
|
|
|
> **Versi Dokumen:** 1.0.0 |
|
|
|
|
> **Terakhir Diperbarui:** 2026-06-25 |
|
|
|
|
> **Status:** Aktif |
|
|
|
|
> **Pemilik:** Tim IT GIS Portal |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Tujuan |
|
|
|
|
|
|
|
|
|
Dokumen ini merupakan **titik masuk utama (Single Entry Point)** bagi seluruh AI Agent dan Developer untuk proyek **geonet-console**. |
|
|
|
|
|
|
|
|
|
Setiap AI **WAJIB** membaca dokumen ini terlebih dahulu sebelum melakukan analisis, implementasi, perubahan kode, refactoring, penghapusan, deployment, maupun pembuatan dokumentasi. |
|
|
|
|
|
|
|
|
|
Dokumen ini **bukan** tempat menyimpan seluruh informasi proyek, melainkan **peta navigasi** menuju seluruh dokumentasi yang tersedia. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Filosofi Proyek |
|
|
|
|
|
|
|
|
|
Proyek ini menerapkan prinsip **AI Native Development**. |
|
|
|
|
|
|
|
|
|
Artinya: |
|
|
|
|
|
|
|
|
|
- Dokumentasi adalah bagian dari source code. |
|
|
|
|
- Setiap perubahan wajib terdokumentasi. |
|
|
|
|
- Repository merupakan sumber kebenaran utama (Single Source of Truth). |
|
|
|
|
- AI tidak boleh mengandalkan riwayat percakapan. |
|
|
|
|
- Seluruh pengetahuan proyek harus tersimpan dalam repository. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Aturan Utama AI |
|
|
|
|
|
|
|
|
|
Sebelum melakukan pekerjaan apa pun, AI wajib: |
|
|
|
|
|
|
|
|
|
1. Membaca file ini. |
|
|
|
|
2. Membaca `docapi/README.md` dan `docapi/index.md`. |
|
|
|
|
3. Memahami arsitektur yang ada (section di bawah). |
|
|
|
|
4. Memastikan tidak ada konflik dengan keputusan sebelumnya. |
|
|
|
|
5. Memperbarui dokumentasi setelah implementasi selesai. |
|
|
|
|
|
|
|
|
|
**Implementasi tanpa dokumentasi dianggap belum selesai.** |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Ringkasan Proyek |
|
|
|
|
|
|
|
|
|
| Item | Nilai | |
|
|
|
|
|------|-------| |
|
|
|
|
| Nama | Geonet Console | |
|
|
|
|
| URL Production | https://console.gisportal.id | |
|
|
|
|
| Framework | Laravel 12 (PHP 8.3) | |
|
|
|
|
| Database App | PostgreSQL Docker (`databaselist_app`) | |
|
|
|
|
| Database Audit | PostgreSQL Docker (`databaselist_audit`) | |
|
|
|
|
| Auth | LDAP Active Directory (`10.100.1.40`) | |
|
|
|
|
| Storage Avatar | QNAP QuObjects OSS (S3-compatible) | |
|
|
|
|
| Deploy | Docker → Nginx reverse proxy `10.100.1.24` | |
|
|
|
|
| Stack path | `/opt/stacks/geonet-console` | |
|
|
|
|
| Port host | `127.0.0.1:8091` → container port `80` | |
|
|
|
|
| Repo path | `server-connection/geonet-console/` | |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Arsitektur Ringkas |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
Browser / my.gisportal.id (Next.js) |
|
|
|
|
│ |
|
|
|
|
▼ |
|
|
|
|
Nginx Reverse Proxy (10.100.1.24) |
|
|
|
|
├── console.gisportal.id → geonet-console:80 (8091) |
|
|
|
|
└── file.gisportal.id/super-apps/ → QNAP OSS (10.100.1.10:8010) |
|
|
|
|
│ |
|
|
|
|
▼ |
|
|
|
|
geonet-console Container (PHP 8.3 + Laravel 12) |
|
|
|
|
├── PHP-FPM + Nginx (dalam container via supervisord) |
|
|
|
|
├── PostgreSQL audit-postgres (container saudara) |
|
|
|
|
├── Active Directory LDAP (10.100.1.40) |
|
|
|
|
├── SQL Server (10.100.1.25:1433) |
|
|
|
|
├── Ollama AI (10.100.1.26:11434) |
|
|
|
|
├── QNAP OSS S3 (10.100.1.10:8010) — avatar storage |
|
|
|
|
└── SMTP (sc138.idcloudhosting.cloud:465) |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Struktur Kode Penting |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
geonet-console/ |
|
|
|
|
├── context-index.md ← FILE INI |
|
|
|
|
├── DOCKGE.md ← Ringkasan deploy & env vars |
|
|
|
|
├── .env.example ← Template env vars (WAJIB BACA sebelum deploy) |
|
|
|
|
├── compose.yaml ← Docker Compose (services, volumes, env) |
|
|
|
|
├── Dockerfile ← Multi-stage build PHP 8.3 + extensions |
|
|
|
|
├── docker/ |
|
|
|
|
│ └── entrypoint.sh ← Startup: migrate, cache, OAuth keys |
|
|
|
|
├── app/ |
|
|
|
|
│ ├── Http/Controllers/Api/V1/ ← Semua API controllers |
|
|
|
|
│ ├── Models/ ← Eloquent models |
|
|
|
|
│ ├── Services/ ← Business logic (LDAP, Auth, DB, dll.) |
|
|
|
|
│ └── Support/ ← ApiActor, helpers |
|
|
|
|
├── config/ |
|
|
|
|
│ ├── filesystems.php ← Disk 'oss' (QNAP OSS S3) |
|
|
|
|
│ └── database.php ← Koneksi pgsql, audit, project_search |
|
|
|
|
├── routes/ |
|
|
|
|
│ └── api.php ← Semua route API v1 |
|
|
|
|
├── database/ |
|
|
|
|
│ └── migrations/ ← Migrasi DB (app, audit, project_search) |
|
|
|
|
└── docapi/ ← Dokumentasi API (WAJIB BACA) |
|
|
|
|
├── README.md |
|
|
|
|
├── index.md ← Daftar semua endpoint |
|
|
|
|
├── authentication.md |
|
|
|
|
└── services/ ← Dokumentasi per service |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Informasi Infrastruktur Kritis |
|
|
|
|
|
|
|
|
|
| Role | IP | SSH Command | |
|
|
|
|
|------|----|-------------| |
|
|
|
|
| Reverse Proxy (deploy target) | 10.100.1.24 | `ssh -m hmac-sha1 root@10.100.1.24 -p 22` | |
|
|
|
|
| Database SQL Server | 10.100.1.25 | `ssh -m hmac-sha1 root@10.100.1.25 -p 22` | |
|
|
|
|
| Active Directory / LDAP | 10.100.1.40 | `ssh -m hmac-sha1 Administrator@10.100.1.40 -p 22` | |
|
|
|
|
| NAS QNAP (OSS storage) | 10.100.1.10 | `ssh -i "$env:USERPROFILE\.ssh\id_ed25519" -o IdentitiesOnly=yes -m hmac-sha1 admin@10.100.1.10 -p 22` | |
|
|
|
|
| Ollama AI | 10.100.1.26 | `ssh -i "$env:USERPROFILE\.ssh\id_rsa_geonet_laptop" -o IdentitiesOnly=yes -m hmac-sha1 root@10.100.1.26 -p 22` | |
|
|
|
|
|
|
|
|
|
> AI **wajib minta persetujuan user** sebelum menjalankan perintah SSH. |
|
|
|
|
|
|
|
|
|
**Stack path di server:** `/opt/stacks/geonet-console/` |
|
|
|
|
**Nginx config:** `/etc/nginx/conf.d/production/geonet-console.conf` |
|
|
|
|
**Env file:** `/opt/stacks/geonet-console/.env` |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Database Connections |
|
|
|
|
|
|
|
|
|
| Connection name | Driver | Host | Database | Dipakai untuk | |
|
|
|
|
|----------------|--------|------|----------|----------------| |
|
|
|
|
| `pgsql` (default) | PostgreSQL | `audit-postgres` (container) | `databaselist_app` | App metadata, user meta, tokens, settings | |
|
|
|
|
| `audit` | PostgreSQL | `audit-postgres` (container) | `databaselist_audit` | Audit log aktivitas | |
|
|
|
|
| `project_search` | PostgreSQL | `10.100.1.25` | `geonet_project_search` | Indeks AI project search | |
|
|
|
|
| `mssql` | SQL Server | `10.100.1.25:1433` | `master` | Database registry (read) | |
|
|
|
|
|
|
|
|
|
> Connection name dipilih via env var `DB_CONNECTION=pgsql`. Jangan ubah ke `sqlite` — migration harus tetap ke PostgreSQL. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Object Storage (Avatar) — QNAP OSS |
|
|
|
|
|
|
|
|
|
| Item | Nilai | |
|
|
|
|
|------|-------| |
|
|
|
|
| Disk Laravel | `oss` (`config/filesystems.php`) | |
|
|
|
|
| Driver | `s3` dengan `use_path_style_endpoint=true` | |
|
|
|
|
| Endpoint internal | `http://10.100.1.10:8010` | |
|
|
|
|
| Bucket | `super-apps` | |
|
|
|
|
| URL publik avatar | `https://file.gisportal.id/super-apps/avatars/<filename>` | |
|
|
|
|
| Nginx proxy | `/etc/nginx/conf.d/nas.conf` → `location /super-apps/` | |
|
|
|
|
| ACL bucket | Public-read (`X-Container-Read: .r:*,.rlistings`) | |
|
|
|
|
|
|
|
|
|
> ⚠️ **Secret Key:** Nilai `OSS_SECRET_ACCESS_KEY` di `.env.example` adalah placeholder. Nilai yang benar ada di `/opt/stacks/geonet-console/.env` server. Jangan commit secret key ke repo. |
|
|
|
|
> |
|
|
|
|
> ⚠️ **Format Access Key:** `super-apps:0Jq7KbF31eJzd4k3LSXN` (format: `<storage-space>:<key-id>`). |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Auth Flow |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
POST /api/v1/auth/login |
|
|
|
|
→ LdapAuthService::attempt() # bind ke AD 10.100.1.40 |
|
|
|
|
→ LdapJwtService::generate() # buat JWT payload (username, groups, ttl) |
|
|
|
|
→ return { token, expires_at } |
|
|
|
|
|
|
|
|
|
GET /api/v1/* dengan Bearer token |
|
|
|
|
→ ApiAuthService::resolve() # decode JWT / lookup API Token |
|
|
|
|
→ ApiActor { identifier, type, groups, scopes } |
|
|
|
|
→ Controller menggunakan ApiActor |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
**LDAP Bind DN:** `Administrator@gisportal.id` |
|
|
|
|
**LDAP Base DN:** `DC=gisportal,DC=id` |
|
|
|
|
**Admin groups:** `Domain Admins`, `Administrators`, `Enterprise Admins` |
|
|
|
|
|
|
|
|
|
> ⚠️ `LDAP_BIND_PASSWORD` di `.env.example` adalah placeholder `change-me`. Nilai asli tersimpan di `.env` server. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## API Kritis |
|
|
|
|
|
|
|
|
|
**Base URL:** `https://console.gisportal.id/api/v1` |
|
|
|
|
**Auth header:** `Authorization: Bearer <token>` |
|
|
|
|
|
|
|
|
|
| Endpoint | Deskripsi | |
|
|
|
|
|----------|-----------| |
|
|
|
|
| `POST /auth/login` | Login LDAP → JWT | |
|
|
|
|
| `POST /auth/refresh` | Refresh JWT | |
|
|
|
|
| `GET /me` | Info user + avatar URL | |
|
|
|
|
| `PUT /me/avatar` | Upload avatar (base64, maks 300KB) | |
|
|
|
|
| `GET /ldap/users` | List user Active Directory | |
|
|
|
|
| `GET /databases` | List database registry | |
|
|
|
|
| `GET /service-tokens` | List service tokens | |
|
|
|
|
| `POST /project-search/ask` | Query AI natural language | |
|
|
|
|
|
|
|
|
|
> Detail lengkap → `docapi/index.md` dan `docapi/services/` |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Cara Deploy |
|
|
|
|
|
|
|
|
|
```powershell |
|
|
|
|
# 1. Build archive (dari Windows) |
|
|
|
|
tar -czf "$env:TEMP\geonet-console.tar.gz" ` |
|
|
|
|
--exclude="vendor" --exclude=".git" --exclude="node_modules" ` |
|
|
|
|
-C "D:\Project\app on git\server-connection\geonet-console" . |
|
|
|
|
|
|
|
|
|
# 2. Upload ke server |
|
|
|
|
Start-Process -FilePath "cmd.exe" -ArgumentList ` |
|
|
|
|
'/c ssh -m hmac-sha1 root@10.100.1.24 -p 22 "cat > /tmp/geonet-console.tar.gz" < "%TEMP%\geonet-console.tar.gz"' ` |
|
|
|
|
-Wait -NoNewWindow |
|
|
|
|
|
|
|
|
|
# 3. Extract & deploy |
|
|
|
|
ssh -m hmac-sha1 root@10.100.1.24 -p 22 " |
|
|
|
|
mkdir -p /opt/stacks/geonet-console && |
|
|
|
|
tar -xzf /tmp/geonet-console.tar.gz -C /opt/stacks/geonet-console && |
|
|
|
|
rm /tmp/geonet-console.tar.gz && |
|
|
|
|
cd /opt/stacks/geonet-console && |
|
|
|
|
docker compose up -d --build --force-recreate |
|
|
|
|
" |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
> ⚠️ **JANGAN overwrite `.env`** saat deploy — file `.env` di server berisi credentials production yang tidak ada di repo. |
|
|
|
|
> ⚠️ Extract **tanpa** `--strip-components` agar struktur folder tetap benar. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Env Vars Kritis |
|
|
|
|
|
|
|
|
|
| Variable | Keterangan | Default aman? | |
|
|
|
|
|----------|------------|---------------| |
|
|
|
|
| `APP_KEY` | Laravel encryption key | Auto-generate jika kosong | |
|
|
|
|
| `LDAP_BIND_PASSWORD` | Password AD bind account | ❌ wajib diisi | |
|
|
|
|
| `APP_DB_PASSWORD` | Password PostgreSQL app | ❌ wajib diisi | |
|
|
|
|
| `OSS_SECRET_ACCESS_KEY` | QNAP OSS secret key | ❌ wajib diisi | |
|
|
|
|
| `MSSQL_PASSWORD` | SQL Server password | ❌ wajib diisi | |
|
|
|
|
| `MAIL_PASSWORD` | SMTP password | ❌ wajib diisi | |
|
|
|
|
| `DB_CONNECTION` | Driver database default | Harus `pgsql` | |
|
|
|
|
|
|
|
|
|
> Lihat `.env.example` untuk daftar lengkap. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Models & Services Utama |
|
|
|
|
|
|
|
|
|
### Models (`app/Models/`) |
|
|
|
|
| Model | Tabel | Keterangan | |
|
|
|
|
|-------|-------|------------| |
|
|
|
|
| `LdapUserMeta` | `ldap_user_meta` | Metadata user LDAP (avatar, settings) | |
|
|
|
|
| `LdapGroupMeta` | `ldap_group_meta` | Metadata group LDAP | |
|
|
|
|
| `DatabaseConnection` | `database_connections` | Registry database | |
|
|
|
|
| `ServiceToken` | `service_tokens` | Token antar-service | |
|
|
|
|
| `AuditLog` | `audit_logs` | Log aktivitas (DB audit) | |
|
|
|
|
| `ApiToken` | `api_tokens` | Personal API Token user | |
|
|
|
|
|
|
|
|
|
### Services (`app/Services/`) |
|
|
|
|
| Service | Tanggung Jawab | |
|
|
|
|
|---------|---------------| |
|
|
|
|
| `LdapAuthService` | Login via LDAP, validasi grup admin | |
|
|
|
|
| `LdapUserService` | CRUD user Active Directory | |
|
|
|
|
| `LdapGroupService` | CRUD group Active Directory | |
|
|
|
|
| `LdapJwtService` | Generate & decode JWT | |
|
|
|
|
| `ApiAuthService` | Resolve token → `ApiActor` | |
|
|
|
|
| `AuditLogService` | Tulis log ke DB audit | |
|
|
|
|
| `DatabaseConnectionManager` | Test & manage koneksi DB external | |
|
|
|
|
| `ProjectSearchService` | Indeks & query AI project search | |
|
|
|
|
| `OllamaService` | Koneksi ke Ollama (LLM) | |
|
|
|
|
| `AgentTokenSyncService` | Sync token dari GeoNetAgent DB | |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Dokumentasi API |
|
|
|
|
|
|
|
|
|
**Lokasi:** `docapi/` |
|
|
|
|
|
|
|
|
|
| File | Isi | |
|
|
|
|
|------|-----| |
|
|
|
|
| `README.md` | Aturan dan checklist API | |
|
|
|
|
| `index.md` | **Daftar semua endpoint** (baca ini dulu) | |
|
|
|
|
| `authentication.md` | Panduan auth (JWT, API Token, scope) | |
|
|
|
|
| `common-response.md` | Format response standar | |
|
|
|
|
| `common-error.md` | Kode error standar | |
|
|
|
|
| `integration-guide.md` | Panduan integrasi service | |
|
|
|
|
| `services/auth/` | Login, refresh, token guide | |
|
|
|
|
| `services/ldap/` | Users & groups LDAP | |
|
|
|
|
| `services/databases/` | Database registry | |
|
|
|
|
| `services/service-tokens/` | Token management | |
|
|
|
|
| `services/project-search/` | AI search | |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Checklist Sebelum Implementasi |
|
|
|
|
|
|
|
|
|
AI wajib memastikan: |
|
|
|
|
|
|
|
|
|
- [ ] Sudah membaca `context-index.md` (file ini) |
|
|
|
|
- [ ] Sudah membaca `docapi/README.md` dan `docapi/index.md` |
|
|
|
|
- [ ] Sudah membaca `DOCKGE.md` jika terkait deploy/env |
|
|
|
|
- [ ] Sudah memahami `config/database.php` jika terkait DB |
|
|
|
|
- [ ] Sudah memahami `config/filesystems.php` jika terkait storage |
|
|
|
|
- [ ] Tidak ada konflik dengan arsitektur yang sudah ada |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Checklist Setelah Implementasi |
|
|
|
|
|
|
|
|
|
AI wajib memperbarui: |
|
|
|
|
|
|
|
|
|
- [ ] `docapi/index.md` — jika ada endpoint baru/berubah |
|
|
|
|
- [ ] `docapi/services/<service>/` — dokumentasi endpoint detail |
|
|
|
|
- [ ] `context-index.md` — jika ada perubahan arsitektur/infrastruktur |
|
|
|
|
- [ ] `.env.example` — jika ada env var baru |
|
|
|
|
- [ ] `mysupperapps_FE_PWA/docs/project/development-log.md` — catat perubahan |
|
|
|
|
- [ ] `mysupperapps_FE_PWA/CHANGELOG.md` — jika perubahan mempengaruhi FE |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Known Issues & Catatan Penting |
|
|
|
|
|
|
|
|
|
- **`project_search` DB:** Connection ke `10.100.1.25` — jika server external tidak reachable, migration akan gagal saat startup. Error ini tidak mempengaruhi fungsi utama app. |
|
|
|
|
- **`DB_CONNECTION=pgsql`** di `compose.yaml` override nilai di `.env`. Jangan ubah ke `sqlite`. |
|
|
|
|
- **OAuth keys** (`storage/oauth-private.key`) di-generate otomatis saat pertama kali container start. Disimpan di Docker volume `app_storage`. |
|
|
|
|
- **Bucket OSS** harus tetap `public-read`. Jika ACL ter-reset, jalankan script Swift API untuk set ulang `X-Container-Read: .r:*,.rlistings`. |
|
|
|
|
- **LDAP_BIND_PASSWORD** di `.env.example` adalah placeholder — selalu cek `/opt/stacks/geonet-console/.env` di server untuk nilai yang benar. |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
|
|
## Penutup |
|
|
|
|
|
|
|
|
|
Repository ini dirancang agar: |
|
|
|
|
|
|
|
|
|
- Developer baru dapat memahami proyek dengan cepat. |
|
|
|
|
- AI Agent mana pun dapat melanjutkan pekerjaan tanpa kehilangan konteks. |
|
|
|
|
- Seluruh pengetahuan proyek tersimpan di dalam repository. |
|
|
|
|
- Dokumentasi selalu selaras dengan implementasi. |
|
|
|
|
|
|
|
|
|
**Repository adalah sumber kebenaran utama.** |
|
|
|
|
|
|
|
|
|
Jika terjadi perbedaan antara implementasi dan dokumentasi, AI wajib memperbarui dokumentasi hingga keduanya konsisten. |