# Arsitektur Super Apps — GIS Portal (`my.gisportal.id`) > Dokumen ini adalah referensi cepat untuk AI agent / developer baru. > Update terakhir: Juni 2026 --- ## Diagram Arsitektur ```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"] end subgraph PROXY["Reverse Proxy (10.100.1.24)"] NGINX["Nginx
(SSL termination, routing)"] 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"] 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"] end subgraph LDAP["Identity (10.100.1.40)"] AD["Windows Server AD
LDAP / Active Directory
User, Group, Auth"] end FE -->|HTTPS| NGINX NGINX -->|":8091"| CONSOLE NGINX -->|":18000"| COLLECTOR CONSOLE -->|LDAP bind| AD CONSOLE --- PGCONSOLE CONSOLE -->|S3 API| OSS COLLECTOR --- PGCOLLECTOR FE -.->|"API /api/v1/*"| CONSOLE FE -.->|"API /api/v1/assets/*"| COLLECTOR FE -.->|"Static file read"| OSS ``` --- ## Komponen FE yang Sudah Ada ```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
(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)"] 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 ``` --- ## Alur Auth & Permission ```mermaid sequenceDiagram participant Browser participant NextJS as my.gisportal.id 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) ``` --- ## Permission System | Permission Key | Fungsi | |---|---| | `profile.view` / `profile.edit` | Halaman profile | | `dashboard.view` | Halaman dashboard | | `asset_mgmt.view` / `asset_mgmt.manage` | Asset Management | | `cmdb.view` / `cmdb.manage` / `cmdb.assign_owner` | CMDB | | `geonet_agent.view` | GeoNet Agent | | `monitoring.view` | Monitoring | | `ticketing.view` / `ticketing.create` / `ticketing.manage` | Ticketing | | `mail.view` | Mail | | `admin.users` / `admin.groups` / `admin.permissions` | Admin panel | Default group mapping (seeder): - **Domain Admins** → semua 17 permissions - **IT-Admin** → 13 permissions - **IT-Staff** → 11 permissions - **Management** → 9 permissions - **Staff/HR** → 6 permissions --- ## Environment Variables Penting ### Frontend (`my-portal` / Next.js) ```env NEXT_PUBLIC_API_URL=https://console.gisportal.id NEXT_PUBLIC_COLLECTOR_URL=https://collector.gisportal.id NEXT_PUBLIC_COLLECTOR_TOKEN= ``` ### Backend `geonet-console` (Laravel, `/opt/stacks/geonet-console`) ```env LDAP_HOST=10.100.1.40 LDAP_PORT=389 LDAP_BASE_DN=DC=geonet,DC=co,DC=id OSS_ENDPOINT=http://10.100.1.10:8010 OSS_BUCKET=super-apps OSS_ACCESS_KEY_ID=super-apps:0Jq7KbF31eJzd4k3LSXN ``` ### Backend `geonet-collector` (FastAPI, `/opt/stacks/geonetagent-collector`) ```env # Source: /opt/stacks/geonetagent-collector/collector-src/ # Docker build context: ./collector-src ``` --- ## Lokasi Server & Deploy | Komponen | Server | Path | Deploy Command | |---|---|---|---| | FE Next.js | 10.100.1.24 | `/opt/stacks/my-portal/` | `docker compose build && up -d` | | geonet-console | 10.100.1.24 | `/opt/stacks/geonet-console/` | `docker compose up -d` | | geonet-collector | 10.100.1.24 | `/opt/stacks/geonetagent-collector/` | `docker compose build && up -d` | | Nginx config | 10.100.1.24 | `/etc/nginx/conf.d/` | `nginx -s reload` | SSH akses: `ssh -m hmac-sha1 root@10.100.1.24 -p 22` --- ## Schema Key — Collector API ### `CollectorAsset` (list item) ```ts { id, hostname, display_name, asset_type, status, manufacturer, model, serial_number, owner_ldap_username, owner_display_name, owner_email, last_seen_at, snapshot_count, primary_physical_mac } ``` ### `CollectorSnapshotSummary` (flat — root level, BUKAN nested .system) ```ts { os_name, os_version, os_build, cpu_model, ram_gb, gpu_model, last_boot_at, agent_version, system?: { form_factor, chassis_label, ... }, cpu?: { model, cores, logical_processors, max_clock_mhz }, disks?: [...], network?: [...], memory_summary?: {...} } ``` --- ## Microservice Yang Direncanakan (Belum Dibangun) | Service | Domain (rencana) | Status | |---|---|---| | Mailcow | `mail.gisportal.id` | 🔴 Belum | | Zammad (ticketing) | `zammad.gisportal.id` | 🔴 Belum | | geonet-content (posting) | `content.gisportal.id` | 🔴 Belum | | geonet-push (push notif VAPID) | `push.gisportal.id` | 🔴 Belum | Lihat `backlog.md` untuk detail tugas dan prioritas pengerjaan.