# AGENTS.md

This file gives future coding agents a fast path map for this repository.

## Repository map

- API entrypoint: `cmd/api/main.go`
- HTTP routes/handlers: `internal/http/handlers.go`
- Core domain logic: `internal/app/service.go`
- Persistence: `internal/store/` — PostgreSQL (when `DATABASE_URL` set) or in-memory; migrations in `internal/store/migrations/`
- Auth utilities: `internal/auth/`
- Frontend static app: `web/`
- TypeScript API client: `libs/geo-api-client/`
- CI workflow: `.gitea/workflows/ci.yml`
- Architecture/planning docs: `docs/`
- Server keys: `etc/` (generated by `./bin/gen-server-keys.sh`)

## Most common commands

From repo root:

```bash
go test ./...
go run ./cmd/api
./bin/gen-server-keys.sh   # before first docker up (creates etc/server-service.*)
./bin/up.sh                # or: docker compose up --build -d
docker compose down
docker compose --profile test run --rm test   # run tests as root (avoids var/ permission issues)
```

TypeScript client:

```bash
cd libs/geo-api-client
bun install
bun test
bun run build
```

## Path conventions

- Use repository-relative paths in docs and comments (never absolute machine paths).
- Keep API route changes in `internal/http/handlers.go`.
- Keep business rule changes in `internal/app/service.go`.
- Keep frontend integration docs under `docs/`.

## Editing guidance for agents

- Prefer minimal changes and avoid unrelated refactors.
- Treat `var/` as runtime data only; ignore it for code changes and commits.
- Every change must be committed and pushed.
- Add tests when behavior changes.
- Verify Go tests after backend changes.
- Verify Bun tests after TS client changes.
- For DB-required tests, prefer embedded/ephemeral Postgres fixtures over relying on an externally managed database.
- If CI fails due runner/network infrastructure, keep logs explicit in workflow output.

## Agent skill memory (current behavior)

- **Asset downloads stay on backend domain:** `GET /v1/assets/{id}/download` streams bytes from backend (no redirect to MinIO/internal URL).
- **Asset uploads are backend-routed:** signed upload endpoint returns backend URL (`/v1/assets/{id}/upload`), browser never uploads directly to MinIO.
- **Public features API exists:** use `GET /v1/features/public` with optional `kind` query (`3d` or `image`) to fetch globally visible features/assets.
- **Feature geometry update API exists:** `PATCH /v1/features/{id}` updates point geometry (owner only).
- **MapLibre demo expectations (`web/maplibre-demo.js`):**
  - uses raster OSM tiles (not vector style),
  - loads all public 3D features on map start,
  - after login merges all owner collections,
  - owner feature markers are draggable and persisted via `PATCH /v1/features/{id}`.
- **Share-link behavior in demos:** "Copy Share Link" generates map URLs with coordinates so recipients open map context, not only raw asset URL.
