# Breadcrumb A self-contained Go server that receives GPS location data from the [Colota Android app](https://colota.app), stores it in an SQLite3 database, and serves a web frontend for browsing trips on a map. ![Breadcrumb screenshot](docs/screenshot.png) ## Quick Start ```bash # Build go build -o breadcrumb . # Run (no auth, default port 8080, db = ./locations.db) ./breadcrumb # Run with Bearer token auth on port 443 ./breadcrumb -port 443 -token mysecrettoken -db /var/data/locations.db ``` ### Flags | Flag | Default | Description | |----------|------------------|------------------------------------------------------| | `-port` | `8080` | HTTP listen port | | `-db` | `locations.db` | Path to the SQLite3 database file | | `-token` | *(empty)* | Bearer token for auth. Empty = authentication off. | --- ## API ### `POST /api/location` ← Colota app sends here **Headers:** `Content-Type: application/json` **Body** (Colota default payload): ```json { "lat": 51.495065, "lon": -0.043945, "acc": 12, "alt": 519, "vel": 0, "batt": 85, "bs": 2, "tst": 1704067200, "bear": 180.5 } ``` | Field | Type | Required | Description | |--------|---------|----------|--------------------------------------------------------| | `lat` | float | ✓ | Latitude (decimal degrees) | | `lon` | float | ✓ | Longitude (decimal degrees) | | `acc` | float | ✓ | Accuracy (metres) | | `tst` | int | ✓ | Unix timestamp (seconds). Falls back to server time. | | `alt` | float | | Altitude (metres) | | `vel` | float | | Speed (m/s) | | `bear` | float | | Bearing (degrees, 0–360) | | `batt` | int | | Battery level (0–100 %) | | `bs` | int | | Battery state: 0=unknown 1=unplugged 2=charging 3=full | **GET** variant is also supported (query parameters with the same field names). **Returns:** `200 OK` on success. --- ### `GET /api/locations` ← Query stored locations | Param | Default | Description | |---------|---------|------------------------------------------| | `limit` | `100` | Max records to return (up to 500 000) | | `page` | `1` | Page number (1-based) | | `from` | | Filter: Unix timestamp lower bound | | `to` | | Filter: Unix timestamp upper bound | **Response:** ```json { "total": 42, "page": 1, "limit": 100, "records": [ { "id": 1, "lat": 51.495065, "lon": -0.043945, ... } ] } ``` --- ### `GET /api/trips` Returns location points grouped into trips (gaps > 30 min = new trip), newest first. --- ### `GET /health` Returns server status and total location count. --- ## Colota App Configuration 1. Open Colota → **Settings → API Settings** 2. Select template: **Custom** 3. Set **Endpoint URL** to `http(s)://your-server:8080/api/location` 4. **HTTP Method:** POST 5. If using a token: set **Authentication → Bearer Token** to your `-token` value 6. Leave field mapping at defaults 7. Tap **Test Connection** — you should see `200 OK` --- ## Docker ```bash docker build -t breadcrumb . docker run -d \ --name breadcrumb \ -p 8080:8080 \ -v breadcrumb-data:/data \ breadcrumb -token "$TOKEN" ``` --- ## Database Schema ```sql CREATE TABLE locations ( id INTEGER PRIMARY KEY AUTOINCREMENT, lat REAL NOT NULL, lon REAL NOT NULL, acc REAL NOT NULL, alt REAL, vel REAL, batt INTEGER, bs INTEGER, tst INTEGER NOT NULL, -- Unix timestamp bear REAL, received_at TEXT NOT NULL -- ISO-8601 UTC ); CREATE INDEX idx_locations_tst ON locations(tst); ```