|
|
|
|
@ -1,104 +1,261 @@
@@ -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<br/>Next.js 16 + React 19<br/>TailwindCSS + shadcn/ui<br/>Zustand + React Query<br/>@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<br/>(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 BACKEND["Backend Services (Docker @ 10.100.1.24)"] |
|
|
|
|
CONSOLE["geonet-console<br/>Laravel 11<br/>console.gisportal.id<br/>Port: 8091→80<br/>Auth, LDAP, Permission,<br/>User Profile, Avatar"] |
|
|
|
|
COLLECTOR["geonet-collector<br/>FastAPI + SQLAlchemy<br/>collector.gisportal.id<br/>agent.gisportal.id<br/>Port: 18000<br/>Asset Mgmt, GeoNet Agent"] |
|
|
|
|
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 STORAGE["Storage"] |
|
|
|
|
PGCONSOLE[("PostgreSQL<br/>geonet-console DB")] |
|
|
|
|
PGCOLLECTOR[("PostgreSQL<br/>collector DB")] |
|
|
|
|
OSS["QNAP QuObjects OSS<br/>S3-compatible<br/>file.gisportal.id<br/>Bucket: super-apps<br/>Avatar, file upload"] |
|
|
|
|
PGCONSOLE[("PostgreSQL\ngeonet-console")] |
|
|
|
|
PGCOLLECTOR[("PostgreSQL\ncollector")] |
|
|
|
|
OSS["QNAP QuObjects OSS\nfile.gisportal.id\nBucket: super-apps"] |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
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<br/>LDAP / Active Directory<br/>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"] |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
subgraph COMPONENTS["Key Components"] |
|
|
|
|
C1["ldap-users-panel.tsx<br/>(Admin: User LDAP mgmt)"] |
|
|
|
|
C2["asset-detail-dialog.tsx<br/>(Asset detail + edit)"] |
|
|
|
|
C3["asset-detail-sheet.tsx<br/>(Asset quick view)"] |
|
|
|
|
C4["device-card.tsx<br/>(Profile: device info)"] |
|
|
|
|
C5["sidebar.tsx + bottom-nav.tsx<br/>(filtered by permission)"] |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
subgraph LIBS["Libs (src/lib)"] |
|
|
|
|
L1["api-client.ts<br/>(geonet-console API)"] |
|
|
|
|
L2["collector-client.ts<br/>(geonet-collector API)"] |
|
|
|
|
L3["ldap-client.ts<br/>(LDAP user/group ops)"] |
|
|
|
|
L4["permissions.ts<br/>(usePermission hooks)"] |
|
|
|
|
L5["auth.ts<br/>(AuthUser interface)"] |
|
|
|
|
L6["constants.ts<br/>(API URLs, tokens)"] |
|
|
|
|
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 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 |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
--- |
|
|
|
|
|