# 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 |
