Update README

This commit is contained in:
Marcus Kida 2026-02-19 17:04:17 +01:00
parent efe55c5990
commit 93e2d4fc46

View file

@ -23,7 +23,8 @@ A web app that visualizes DMR repeaters on an interactive map. Filter by band an
## Tech Stack ## Tech Stack
- **Backend:** Go (stdlib `net/http`), PostgreSQL 17 via `pgx/v5`, migrations via `goose/v3` - **Backend:** Go (stdlib `net/http`), PostgreSQL 17 via `pgx/v5`, migrations via `goose/v3`
- **Frontend:** Vanilla JavaScript, Leaflet, i18next — no build step - **Frontend:** TypeScript (bundled with esbuild), Leaflet, i18next
- **Testing:** Vitest (92 unit tests)
- **Infrastructure:** Docker Compose, multi-stage Dockerfile - **Infrastructure:** Docker Compose, multi-stage Dockerfile
## External Services ## External Services
@ -36,7 +37,7 @@ A web app that visualizes DMR repeaters on an interactive map. Filter by band an
| [Nominatim](https://nominatim.openstreetmap.org) | Address geocoding and autocomplete (client-side) | None | | [Nominatim](https://nominatim.openstreetmap.org) | Address geocoding and autocomplete (client-side) | None |
| [OSRM](https://project-osrm.org) | Driving route calculation (client-side) | None | | [OSRM](https://project-osrm.org) | Driving route calculation (client-side) | None |
The BrandMeister talk group registry is fetched once at Docker build time and bundled as `static/talkgroups.json`. It is used for talk group name resolution and autocomplete in CPS Studio. The BrandMeister talk group registry is fetched once at Docker build time and bundled as `frontend/static/talkgroups.json`. It is used for talk group name resolution and autocomplete in CPS Studio.
## Running with Docker ## Running with Docker
@ -48,7 +49,7 @@ Open http://localhost:8080. PostgreSQL data is persisted in a named volume.
## Development ## Development
Hot-reload with [air](https://github.com/air-verse/air): Hot-reload with [air](https://github.com/air-verse/air) (Go) and esbuild watch (TypeScript):
```sh ```sh
docker compose -f compose.dev.yml up --build docker compose -f compose.dev.yml up --build
@ -56,6 +57,12 @@ docker compose -f compose.dev.yml up --build
The dev container mounts the project directory, so changes to Go and frontend files are picked up automatically. The dev container mounts the project directory, so changes to Go and frontend files are picked up automatically.
### Running Tests
```sh
docker compose -f compose.test.yml run --rm test
```
## Environment Variables ## Environment Variables
| Variable | Default | Description | | Variable | Default | Description |
@ -64,6 +71,8 @@ The dev container mounts the project directory, so changes to Go and frontend fi
| `JSON_PATH` | `rptrs.json` | Path to RadioID repeater dump | | `JSON_PATH` | `rptrs.json` | Path to RadioID repeater dump |
| `BMRPTRS_PATH` | `bmrptrs.json` | Path to BrandMeister repeater dump | | `BMRPTRS_PATH` | `bmrptrs.json` | Path to BrandMeister repeater dump |
| `LISTEN_ADDR` | `:8080` | HTTP listen address | | `LISTEN_ADDR` | `:8080` | HTTP listen address |
| `STATIC_DIR` | `static` | Path to static frontend assets |
| `MIGRATIONS_DIR` | `migrations` | Path to SQL migration files |
| `BM_SYNC` | *(disabled)* | Set to `true` to enable periodic BrandMeister device sync | | `BM_SYNC` | *(disabled)* | Set to `true` to enable periodic BrandMeister device sync |
| `ADMIN_TOKEN` | *(disabled)* | Set to enable the admin interface at `/admin/` | | `ADMIN_TOKEN` | *(disabled)* | Set to enable the admin interface at `/admin/` |
@ -80,23 +89,34 @@ The dev container mounts the project directory, so changes to Go and frontend fi
## Project Structure ## Project Structure
``` ```
├── main.go # Route registration, env config ├── backend/
├── db.go # DB queries, Repeater struct, geo helpers │ ├── main.go # Route registration, env config
├── handlers.go # Public API handlers │ ├── db.go # DB queries, Repeater struct, geo helpers
├── admin.go # Admin auth middleware + admin API │ ├── handlers.go # Public API handlers
├── bmdevice.go # BrandMeister device sync │ ├── admin.go # Admin auth middleware + admin API
├── migrations/ # SQL migrations (goose) │ ├── bmdevice.go # BrandMeister device sync
├── static/ │ ├── seed.go # Database seeding from JSON dumps
│ ├── app.js # Frontend application logic │ ├── migrate.go # Goose migration runner
│ ├── style.css # Styles with dark mode support │ ├── go.mod / go.sum
│ ├── index.html # Single-page HTML shell │ ├── migrations/ # SQL migrations (goose)
│ ├── i18n.js # i18next initialization │ └── data/ # RadioID + BrandMeister JSON dumps
│ ├── locales/ # Translation files (en, de, es, fr, it, pl) ├── frontend/
│ └── lib/ # Vendored JS libraries (Leaflet, i18next, socket.io) │ ├── src/ # TypeScript source + tests
│ ├── static/
│ │ ├── index.html # Single-page HTML shell
│ │ ├── admin.html # Admin interface
│ │ ├── style.css # Styles with dark mode support
│ │ ├── i18n.js # i18next initialization
│ │ ├── locales/ # Translation files (en, de, es, fr, it, pl)
│ │ └── lib/ # Vendored JS libraries (Leaflet, i18next, socket.io)
│ ├── package.json
│ ├── tsconfig.json
│ └── vitest.config.ts
├── Dockerfile # Production multi-stage build ├── Dockerfile # Production multi-stage build
├── Dockerfile.dev # Development image with air ├── Dockerfile.dev # Development image with air + esbuild
├── compose.yml # Production Docker Compose ├── compose.yml # Production Docker Compose
└── compose.dev.yml # Development Docker Compose ├── compose.dev.yml # Development Docker Compose
└── compose.test.yml # Test runner Docker Compose
``` ```
## Data ## Data