diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index a1b1ed2..35c5f9c 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -1,104 +1,261 @@
# Arsitektur Super Apps — GIS Portal (`my.gisportal.id`)
> Dokumen ini adalah referensi cepat untuk AI agent / developer baru.
-> Update terakhir: Juni 2026
+> Update terakhir: Juli 2026
---
-## Diagram Arsitektur
+## 1. Arsitektur Keseluruhan (High-Level)
```mermaid
graph TB
- subgraph CLIENT["Client (Browser / PWA)"]
- FE["my.gisportal.id
Next.js 16 + React 19
TailwindCSS + shadcn/ui
Zustand + React Query
@ducanh2912/next-pwa"]
+ subgraph USER["Pengguna"]
+ BROWSER["Browser / PWA\nmy.gisportal.id"]
+ AGENT["GeoNet Agent\n(Windows PC/Laptop)"]
end
- subgraph PROXY["Reverse Proxy (10.100.1.24)"]
- NGINX["Nginx
(SSL termination, routing)"]
+ subgraph SERVER24["App Server — 10.100.1.24 (Docker)"]
+ NGINX["Nginx\nReverse Proxy + SSL"]
+
+ subgraph APPS["Aplikasi"]
+ FE["my-portal\nNext.js 16 + React 19\nmy.gisportal.id"]
+ CONSOLE["geonet-console\nLaravel 11\nconsole.gisportal.id"]
+ COLLECTOR["geonet-collector\nFastAPI\nagent.gisportal.id"]
+ ZAMMAD["Zammad ⏳\nTicketing\nticket.gisportal.id"]
+ end
+
+ subgraph OPS["Operasional"]
+ GRAFANA["Grafana + Loki\nMonitoring & Log"]
+ N8N["n8n\nAutomation"]
+ NODERED["Node-RED\nWorkflow"]
+ UPTIME["Uptime Kuma\nUptime Monitor"]
+ DOCKGE["Dockge\nDocker Manager"]
+ end
end
- subgraph BACKEND["Backend Services (Docker @ 10.100.1.24)"]
- CONSOLE["geonet-console
Laravel 11
console.gisportal.id
Port: 8091→80
Auth, LDAP, Permission,
User Profile, Avatar"]
- COLLECTOR["geonet-collector
FastAPI + SQLAlchemy
collector.gisportal.id
agent.gisportal.id
Port: 18000
Asset Mgmt, GeoNet Agent"]
+ subgraph STORAGE["Storage"]
+ PGCONSOLE[("PostgreSQL\ngeonet-console")]
+ PGCOLLECTOR[("PostgreSQL\ncollector")]
+ OSS["QNAP QuObjects OSS\nfile.gisportal.id\nBucket: super-apps"]
end
- subgraph STORAGE["Storage"]
- PGCONSOLE[("PostgreSQL
geonet-console DB")]
- PGCOLLECTOR[("PostgreSQL
collector DB")]
- OSS["QNAP QuObjects OSS
S3-compatible
file.gisportal.id
Bucket: super-apps
Avatar, file upload"]
+ subgraph IDENTITY["Identity — 10.100.1.40"]
+ AD["Windows AD\nLDAP / Active Directory"]
end
- subgraph LDAP["Identity (10.100.1.40)"]
- AD["Windows Server AD
LDAP / Active Directory
User, Group, Auth"]
+ subgraph PLANNED["Direncanakan ⏳"]
+ MAILCOW["Mailcow\nmail.gisportal.id"]
+ CONTENT["geonet-content\nPosting/Feed"]
+ PUSH["geonet-push\nPush Notification"]
end
- FE -->|HTTPS| NGINX
- NGINX -->|":8091"| CONSOLE
- NGINX -->|":18000"| COLLECTOR
+ BROWSER -->|HTTPS| NGINX
+ AGENT -->|HTTPS POST report| NGINX
+ NGINX --> FE
+ NGINX --> CONSOLE
+ NGINX --> COLLECTOR
+ NGINX -.-> ZAMMAD
+
CONSOLE -->|LDAP bind| AD
CONSOLE --- PGCONSOLE
CONSOLE -->|S3 API| OSS
+ CONSOLE -.->|"create ticket ⏳"| ZAMMAD
+
COLLECTOR --- PGCOLLECTOR
- FE -.->|"API /api/v1/*"| CONSOLE
- FE -.->|"API /api/v1/assets/*"| COLLECTOR
- FE -.->|"Static file read"| OSS
+ FE -->|"API /api/v1/*"| CONSOLE
+ FE -->|"API assets/*"| COLLECTOR
+ FE -.->|"Static files"| OSS
```
---
-## Komponen FE yang Sudah Ada
+## 2. Arsitektur Backend Services
```mermaid
graph LR
- subgraph PAGES["Pages (src/app/(app))"]
- P1["/dashboard"]
- P2["/profile"]
- P3["/asset-management"]
- P4["/admin/permissions"]
- P5["/(app)/layout → AuthGuard"]
+ subgraph CONSOLE["geonet-console (Laravel 11)"]
+ direction TB
+ AUTH["Auth\nLDAP login\nJWT token"]
+ ME["Profile /me\navatar OSS"]
+ PERM["Permissions\ngroup_permissions\nLDAP group mapping"]
+ ASSET_C["Asset API\nbridge ke collector"]
+ FEEDBACK["Feedback\nPOST /feedback\nbug & saran"]
+ SVCTOKEN["Service Tokens\nmicroservice auth"]
+ LDAPMGMT["LDAP Management\nuser, group CRUD"]
end
- subgraph COMPONENTS["Key Components"]
- C1["ldap-users-panel.tsx
(Admin: User LDAP mgmt)"]
- C2["asset-detail-dialog.tsx
(Asset detail + edit)"]
- C3["asset-detail-sheet.tsx
(Asset quick view)"]
- C4["device-card.tsx
(Profile: device info)"]
- C5["sidebar.tsx + bottom-nav.tsx
(filtered by permission)"]
+ subgraph COLLECTOR["geonet-collector (FastAPI)"]
+ direction TB
+ INGEST["Agent Ingest\nPOST /report"]
+ ASSETS["Asset CRUD\nlist, detail, edit"]
+ SNAP["Snapshots\nhardware history"]
+ AUDIT_C["Audit Log\nperubahan aset"]
end
- subgraph LIBS["Libs (src/lib)"]
- L1["api-client.ts
(geonet-console API)"]
- L2["collector-client.ts
(geonet-collector API)"]
- L3["ldap-client.ts
(LDAP user/group ops)"]
- L4["permissions.ts
(usePermission hooks)"]
- L5["auth.ts
(AuthUser interface)"]
- L6["constants.ts
(API URLs, tokens)"]
- end
+ PGCON[("PostgreSQL\ngeonet-console")]
+ PGCOL[("PostgreSQL\ncollector")]
+ AD2["Active Directory\n10.100.1.40"]
+ OSS2["QNAP OSS\nfile.gisportal.id"]
+
+ AUTH -->|bind| AD2
+ ME --> OSS2
+ CONSOLE --- PGCON
+ COLLECTOR --- PGCOL
+ ASSET_C -->|HTTP| COLLECTOR
```
---
-## Alur Auth & Permission
+## 3. Alur Auth & Permission
```mermaid
sequenceDiagram
participant Browser
- participant NextJS as my.gisportal.id
+ participant FE as my-portal (Next.js)
+ participant Console as geonet-console
+ participant AD as Active Directory (LDAP)
+
+ Browser->>FE: POST /api/login {username, password}
+ FE->>Console: POST /api/v1/auth/login
+ Console->>AD: LDAP bind — verifikasi kredensial
+ AD-->>Console: OK + groups[]
+ Console->>Console: Resolve permissions dari group_permissions
+ Console-->>FE: {token, username, groups[], permissions[]}
+ FE-->>Browser: Set httpOnly cookie → redirect /dashboard
+
+ Browser->>FE: GET /dashboard
+ FE->>Console: GET /api/v1/me (Bearer token)
+ Console-->>FE: {username, display_name, groups[], permissions[]}
+ FE-->>Browser: Render sidebar/nav (filter by permissions)
+```
+
+---
+
+## 4. Alur GeoNet Agent (PC Reporting)
+
+```mermaid
+sequenceDiagram
+ participant PC as Windows PC/Laptop
+ participant GPO as Group Policy (AD)
+ participant Agent as GeoNet Agent Script
+ participant Collector as geonet-collector
+
+ GPO->>PC: Startup/Shutdown Task trigger
+ PC->>Agent: Jalankan UserAgent.ps1
+ Agent->>Agent: Kumpulkan data hardware\n(CPU, RAM, Disk, GPU, Network, OS)
+ Agent->>Agent: Cek versi manifest.json\nauto-update jika ada versi baru
+ Agent->>Collector: POST /api/v1/agent/report\n{hostname, snapshot, ...}
+ Collector->>Collector: Simpan asset + snapshot
+ Collector-->>Agent: 200 OK
+
+ Note over PC,Agent: Task: GeoNetAgent-Report-Startup\nGeoNetAgent-Report-Logon\nGeoNetAgent-Report-Shutdown
+```
+
+---
+
+## 5. Alur Feedback → Tiket (Rencana Integrasi Zammad)
+
+```mermaid
+sequenceDiagram
+ participant User as User (Browser)
+ participant FE as my-portal
participant Console as geonet-console
- participant AD as Active Directory
-
- Browser->>NextJS: POST /api/login {username, password}
- NextJS->>Console: POST /api/v1/auth/login
- Console->>AD: LDAP bind (verify credentials)
- AD-->>Console: OK + user groups
- Console-->>NextJS: {token, user, groups[], permissions[]}
- NextJS-->>Browser: Set cookie + redirect /dashboard
-
- Browser->>NextJS: GET /dashboard
- NextJS->>Console: GET /api/v1/me (Bearer token)
- Console-->>NextJS: {username, display_name, groups[], permissions[]}
- NextJS-->>Browser: Render (sidebar/nav filtered by permissions)
+ participant Zammad as Zammad ⏳
+
+ User->>FE: Klik tombol Feedback
+ FE->>FE: Tampilkan FeedbackDialog\n(form bug/saran + auto-capture page, user, timestamp)
+ User->>FE: Isi form & klik Kirim
+ FE->>Console: POST /api/v1/feedback\n{type, title, message, context}
+ Console->>Console: Simpan ke tabel feedback
+ Console-->>FE: {id, status: open}
+ Console-)Zammad: POST /api/v1/tickets ⏳\nauto-create tiket
+ FE-->>User: Tampilkan nomor tiket + pesan sukses
+```
+
+---
+
+## 6. Peta Halaman Frontend
+
+```mermaid
+graph TD
+ subgraph AUTH["Autentikasi"]
+ LOGIN["/login"]
+ end
+
+ subgraph APP["App (AuthGuard + Layout)"]
+ DASH["/dashboard"]
+ PROFILE["/profile"]
+
+ subgraph ASSET["Asset Management"]
+ ASSETLIST["/asset-management"]
+ end
+
+ subgraph ADMIN["Admin (admin.*)"]
+ USERS["/admin/users"]
+ GROUPS["/admin/groups"]
+ PERMS["/admin/permissions"]
+ end
+
+ subgraph PLANNED2["Direncanakan ⏳"]
+ TICKET["/ticket\n→ Zammad"]
+ MAIL["/mail\n→ Mailcow"]
+ MONITOR["/monitoring\n→ Grafana"]
+ NOTIF["/notification\n→ Push Service"]
+ ATTEND["/attendance"]
+ LEAVE["/leave"]
+ end
+
+ FEEDBACK_BTN["FeedbackButton\n(floating, semua halaman)"]
+ end
+
+ LOGIN --> DASH
+ DASH --- PROFILE
+ DASH --- ASSETLIST
+ DASH --- ADMIN
+ DASH --- PLANNED2
+ FEEDBACK_BTN -.->|"POST /api/v1/feedback"| CONSOLE2["geonet-console"]
+```
+
+---
+
+## 7. Infrastruktur & Topologi Jaringan
+
+```mermaid
+graph TB
+ subgraph INTERNET["Internet"]
+ USERS2["Pengguna Eksternal"]
+ end
+
+ subgraph LAN["LAN — 10.100.1.x"]
+ GW["Mikrotik Gateway\n10.100.1.1"]
+
+ subgraph SERVERS["Servers"]
+ S24["10.100.1.24\nApp Server\n(Docker: portal, console,\ncollector, nginx, monitoring)"]
+ S25["10.100.1.25\nMain Database\n(PostgreSQL)"]
+ S40["10.100.1.40\nAD-LDAP\n(Active Directory)"]
+ S42["10.100.1.42\nZabbix\n(Network Monitor)"]
+ S26["10.100.1.26\nOllama\n(AI Inference CPU)"]
+ QNAP["10.100.1.10\nNAS QNAP TS-932X\n(OSS S3, NFS)"]
+ end
+
+ subgraph PROXMOX["Proxmox Hypervisor"]
+ PDEV["10.100.1.101\nDev Proxmox"]
+ POPR["10.100.1.102\nOpr Proxmox\n(VM 103: monitoring)"]
+ end
+
+ subgraph ARCGIS["ArcGIS Enterprise (Dev)"]
+ A51["10.100.1.51\nArcGIS Base\n(Portal + Server + DS Relational)"]
+ A52["10.100.1.52\nArcGIS DS Object"]
+ A53["10.100.1.53\nArcGIS DS Spatio"]
+ end
+ end
+
+ USERS2 -->|HTTPS| GW
+ GW --> S24
+ S24 --> S25
+ S24 --> S40
+ S24 --> QNAP
```
---