# Frontend Development Development guide for the demo frontend in `web/` and the reusable TypeScript client in `libs/geo-api-client`. ## Architecture - `web/` is a no-bundler Vue + Vuetify app served directly by the Go backend at `/web/`. - `libs/geo-api-client` contains signed auth and API request logic reused by frontend code. - Asset binaries are stored in S3-compatible storage, while frontend works with metadata and service-relative links returned by the API. ## Demo app (`web/`) ### File map ```text web/ ├── index.html # Entry page, loads Vue/Vuetify from CDN ├── app.js # Main app state and handlers ├── api.js # GeoApiClient wrapper for browser usage ├── qr.js # QR code generation for key sharing/backup └── scanner.js # Camera QR scanner for key import ``` ### Local run 1. Start backend: ```bash go run ./cmd/api # or docker compose up -d ``` 2. Open: - `http://localhost:8122/web/` - `http://localhost:8122/web/leaflet-demo.html` (Leaflet map demo for 3D/image placement + sharing) - `http://localhost:8122/web/maplibre-demo.html` (MapLibre GL raster tiles + Three.js GLB/GLTF object rendering/placement) ### Runtime dependencies - Vue 3 and Vuetify 3 from CDN (no package manager in `web/`) - `libs/geo-api-client/dist/index.js` (ESM build artifact) - `qrcode` via `esm.sh` in `qr.js` - `jsQR` via `esm.sh` in `scanner.js` ### Supported UI flows - Connection and identity: - API URL configuration - key generation - pk/pb display and QR export - restore/import keypair from QR - register and login - Collection management: - create, select, rename, delete - Feature management: - add/list/delete points - lon/lat validation (`-180..180`, `-90..90`) - Asset-ready feature rendering: - read linked media from `feature.properties.assets` - use relative `link` value (for example `/v1/assets/{id}/download`) for fetch/open - Leaflet map example: - click map to place object coordinates - create feature + upload/link `gltf`/`glb`/image asset - upload via backend endpoint (`/v1/assets/{id}/upload`) - copy/open share link and toggle public/private visibility - MapLibre GL + Three.js example: - raster OSM basemap via MapLibre style - map click to place object position - custom Three.js layer loads real `glb`/`gltf` assets via `GLTFLoader` - private assets are loaded with bearer auth header when user is logged in - fallback primitive is rendered if model load fails or no 3D asset is linked - asset upload/link and share/visibility controls backed by API ## TypeScript client (`libs/geo-api-client`) The TypeScript client centralizes auth signatures and API requests. ```bash cd libs/geo-api-client bun install bun test bun run build ``` After client changes, rebuild before loading the demo app. Docker image builds handle this automatically. ## Frontend implementation notes for assets - Treat `properties.assets` as backend-owned metadata. Do not derive URLs in frontend from S3 config. - Always use backend-provided relative `link` for downloads so permission checks remain server-side. - When asset visibility changes (`isPublic`), refresh affected feature list to keep UI in sync. ## Related docs | Document | Description | |----------|-------------| | [TypeScript Frontend Integration](typescript-frontend-integration.md) | API client usage and integration flow | | [Assets Storage and Sharing](assets-storage-and-sharing.md) | Asset lifecycle, deduplication, visibility, API endpoints | | [Docker MinIO Local Development](docker-minio-local-dev.md) | Local object storage topology and verification | | [Ed25519 Security Use Cases](ed25519-security-use-cases.md) | Auth and signature behavior | | [Geo Auth Backend Plan](geo-auth-backend-plan.md) | Architecture and planning history |