# Copilot Instructions for line-of-sight

## Purpose
This repository is a full-stack geospatial app:
- `frontend/`: React + Vite + MapLibre UI
- `backend/`: Express API with PostGIS queries
- `docker/` and `docker-compose.yml`: local orchestration and DB initialization

Prefer small, focused changes that keep frontend/backend contracts stable.

## First Commands to Know
Use these commands first when validating changes.

### Docker-first workflow (preferred)
- Start stack: `docker-compose up --build`
- Stop stack: `docker-compose down`
- Backend tests: `docker-compose exec backend npm test`
- Frontend unit tests: `docker-compose exec frontend npm test -- --run`
- Frontend E2E tests: `docker-compose exec frontend npm run test:e2e`
- Seed geodata: `docker-compose exec backend npm run seed-data`

### Local workflow (without Docker)
- Root Node version: `nvm use` (uses `.nvmrc`, currently Node 24)
- Backend dev: `cd backend && npm install && npm run dev`
- Frontend dev: `cd frontend && npm install && npm run start`

## Architecture and Boundaries
- Backend API entrypoint: `backend/app/server.js`
  - Defines `GET /api/line-of-sight` and `GET /api/health`
  - Performs destination/path generation and PostGIS querying
- Frontend app entrypoint: `frontend/src/App.jsx`
  - Owns map lifecycle, animation, and UI state
  - Calls backend via `frontend/src/services/api.js`
- Database bootstrap: `docker/init.sql`
  - Enables PostGIS and creates `cities` with spatial index

When changing behavior, prefer backend geospatial logic over duplicating calculations in the frontend.

## Project Conventions
- Keep geospatial coordinates in WGS84 (`SRID 4326`) and preserve existing lat/lon parameter naming.
- Keep API responses JSON-compatible and backward compatible unless explicitly requested.
- Keep frontend styles in `frontend/src/styles/` (project uses custom CSS, not utility CSS frameworks).
- Avoid broad refactors in `App.jsx` unless task requires it; map lifecycle and refs are tightly coupled.

## Testing Expectations
- Backend tests live in `backend/tests/` and use Jest + Supertest.
- Frontend unit tests live in `frontend/src/__tests__/` and use Vitest + Testing Library.
- E2E tests live in `frontend/e2e/` and use Playwright.
- For feature changes:
  - Run the closest unit tests first.
  - Run E2E tests when user flows or map interactions are changed.

## Common Pitfalls
- PostGIS must be available before backend geospatial endpoints are exercised.
- `docker-compose.yml` pins Postgres service to `linux/arm64`; this can affect non-ARM hosts.
- Data import script (`backend/scripts/import_cities.js`) depends on `wget` and `unzip` availability.
- `README.md` contains roadmap/history notes; trust current scripts/config in source files first.

## CI Notes
CI config is in `.gitea/workflows/test.yml`.
- Backend and frontend tests run on Node 24.
- Frontend unit tests run with `npm test -- --run`.
- E2E runs in Playwright container.

## Link, Do Not Duplicate
For detailed setup and product context, reference:
- `README.md`
- `GEMINI.md`

Keep this file focused on actionable agent guidance and repo-specific guardrails.