# Architecture — Request Flow > **Terakhir Diperbarui:** 2026-06-29 --- ## Alur Request Browser → API ```mermaid sequenceDiagram participant B as Browser / Next.js participant NGX as Nginx (10.100.1.24) participant GC as geonet-console (:8091) participant DB as PostgreSQL (audit-postgres) participant LOG as Audit DB B->>NGX: HTTPS GET console.gisportal.id/api/v1/ldap/users NGX->>GC: proxy_pass 127.0.0.1:8091 GC->>GC: Middleware: auth (ApiAuthService::resolve) GC->>GC: Rate limit check GC->>GC: Controller → LdapUserService GC->>DB: Query jika diperlukan (ldap_user_meta) DB-->>GC: data GC->>LOG: AuditLogService::log() (untuk write actions) GC-->>NGX: JSON response NGX-->>B: JSON response ``` --- ## Middleware Stack (geonet-console) | Middleware | Fungsi | |-----------|--------| | `throttle:60,1` (general) | Rate limit umum | | `throttle:5,1` (login) | Rate limit login | | `auth.api` | Resolve Bearer token → ApiActor | | `scope:` | Cek scope/ability token | --- ## Route Groups ``` /api/v1/auth/* — Public (tidak butuh auth) /api/v1/me — Auth: JWT atau API Token /api/v1/ldap/* — Auth + scope: ldap:read / ldap:write /api/v1/databases/* — Auth + scope: databases:read / databases:write /api/v1/service-tokens/*— Auth (JWT atau token dengan akses service) /api/v1/project-search/*— Auth + scope: project-search:read ``` --- ## File Upload Flow (Avatar) ``` Client → PUT /api/v1/me/avatar {data: base64} → geonet-console: decode base64 → Storage::disk('oss')->put('avatars/', $content) → QNAP OSS (http://10.100.1.10:8010) → ldap_user_meta.avatar = 'avatars/' (path relatif) → return {avatar_url: 'https://file.gisportal.id/super-apps/avatars/'} ``` Avatar URL: via Nginx proxy `/super-apps/` → QNAP OSS → bucket `super-apps` (public-read)