Files
(jenkins) 228032c913
Tests / backend-test (pull_request) Successful in 10s
Tests / frontend-test (pull_request) Successful in 9m25s
Tests / e2e-test (pull_request) Has been cancelled
Update application ports to 3050 and enhance Playwright tests with WebGL mock
2026-04-01 11:04:16 +01:00

113 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What This Project Is
**Line of Sight** is a geospatial web app that draws a great-circle line from a user-selected point on Earth in a chosen direction, then finds all cities along that path. It includes a flight-over animation that speeds up 20x over water and slows to normal speed over land.
## Commands
### Docker (preferred workflow)
```bash
docker-compose up --build # Start all services (frontend :3050, backend :3001, postgres)
docker-compose down # Stop all services
docker-compose logs -f # View logs
# Run tests inside containers
docker-compose exec backend npm test
docker-compose exec frontend npm test -- --run
docker-compose exec frontend npm run test:e2e
```
### Local development (without Docker)
```bash
# Backend
cd backend && npm run dev # Nodemon dev server on :3001
# Frontend
cd frontend && npm run start # Vite dev server on :3050
```
### Tests
```bash
# Backend unit tests (Jest + Supertest)
cd backend && npm test
# Frontend unit tests (Vitest)
cd frontend && npm test # Watch mode
cd frontend && npm test -- --run # Single run (CI mode)
# E2E tests (Playwright)
cd frontend && npm run test:e2e
# Seed the database with GeoNames city data
cd backend && npm run seed-data
```
### Build
```bash
cd frontend && npm run build # Vite production build → frontend/build/
```
## Architecture
This is a monorepo with three services orchestrated by Docker Compose:
```
frontend/ → React 19 + Vite 6 SPA (MapLibre GL, Turf.js, Axios)
backend/ → Node 24 + Express 5 REST API
docker/ → PostgreSQL + PostGIS initialization
```
### Data flow
1. User clicks map → sets start point (lat/lon)
2. User selects direction (0360°) and tolerance (km radius)
3. Frontend calls `GET /api/line-of-sight?lat=&lon=&direction=&tolerance=`
4. Backend generates 80 path points along a great-circle arc (up to 20,000 km)
5. For each point, a PostGIS `ST_DWithin()` query finds cities within tolerance
6. Backend also checks whether each point is over land (500 km radius land check)
7. Response includes line coordinates with per-point water flags and matching cities
8. Frontend renders the path on a 3D globe map and shows city markers
### Backend: `backend/app/server.js`
Single-file Express app. Key internals:
- `calculateDestination()` — Haversine formula for great-circle destination points
- `GET /api/line-of-sight` — main endpoint: path generation + PostGIS city lookup
- `GET /api/health` — health check
- Returns up to 200 cities ordered by position along the line
### Frontend: `frontend/src/App.jsx`
Single large React component (~687 lines) managing all state and map logic:
- MapLibre GL map with 3D globe projection and terrain/sky effects
- Direction slider drives a live preview line before the user commits
- After "Show Line of Sight", map locks (prevents moving start point)
- Flight animation uses Turf.js to interpolate positions along the path; speed is 1× over land, 20× over water with smooth acceleration (0.005 step), predictive look-ahead of 2000 km
- New cities are fetched every 2000 km during flight via the same API
- Three map styles: light, dark, satellite (Esri tiles)
### Database
PostGIS `cities` table with a GIST index on `geom GEOGRAPHY(POINT, 4326)`. All coordinates use WGS84 / SRID 4326. The init SQL seeds 10 major cities; the `seed-data` script imports from GeoNames for a fuller dataset.
## Conventions
- **Geospatial**: WGS84 / SRID 4326 everywhere; PostGIS `GEOGRAPHY` type for distance queries
- **API**: RESTful; query params for `GET /api/line-of-sight`; env var `VITE_API_URL` (frontend) or `DATABASE_URL` (backend)
- **Styling**: Plain CSS files in `frontend/src/styles/` — no CSS framework
- **Tests**: Backend mocks the `pg` Pool; frontend mocks MapLibre GL and the API service. E2E tests use Playwright with a mock API response
## CI
Gitea workflow (`.gitea/workflows/test.yml`) runs on push/PR to `main`:
1. **backend-test**`npm ci && npm test`
2. **frontend-test**`npm ci && npm test -- --run`
3. **e2e-test** — uses `mcr.microsoft.com/playwright:v1.50.1` container