# CargoRadar

CargoRadar is an MVP for tracking freight drivers from an Android app and
monitoring their latest positions from a web control screen.

## Current Shape

- `apps/server`: Node.js API server with no external runtime dependencies.
- `apps/web`: Static control web UI served by the API server.
- `apps/android`: Kotlin Android driver-app skeleton.
- `runtime-data`: Docker runtime data directory, created on first run.

## Run Locally

If Node.js is installed:

```powershell
node apps/server/src/server.js
```

Open:

```text
http://localhost:8080
```

The web screen has a `샘플 전송` button that posts a demo location with the
default `demo-token`.

By default the server also runs a test simulator with 10 vehicles moving around
Korea. Disable it when real driver phones are connected:

```text
SIMULATOR_ENABLED=false
```

## Run With Docker

```powershell
copy .env.example .env
docker compose up --build
```

Open:

```text
http://localhost:8080
```

On Synology NAS, the same `docker-compose.yml` can be used through Container
Manager or SSH. Keep `runtime-data` mounted so driver tokens and location
history survive container restarts.

For NAS, use `.env.nas.example` as the starting point and prefer port `18081`
behind Synology Reverse Proxy.

During early testing, keep `SIMULATOR_ENABLED=true` to show moving demo
vehicles without Android phones. The simulator publishes fresh locations every
`SIMULATOR_INTERVAL_MS` milliseconds, 5000 ms by default. It follows cached
Kakao Mobility road routes when `KAKAO_REST_API_KEY` is valid, uses OSRM road
routes as a demo fallback, and only then falls back to an internal route.
`SIMULATOR_SPEED_SCALE` defaults to 1 so the map movement stays close to the
displayed vehicle speed.

## Maintenance Scripts

Check server status:

```powershell
.\scripts\health-check.ps1 -BaseUrl "http://127.0.0.1:8080"
```

Send a demo location:

```powershell
.\scripts\post-demo-location.ps1 -BaseUrl "http://127.0.0.1:8080"
```

Back up runtime data:

```powershell
.\scripts\backup-runtime-data.ps1
```

## Kakao Map

The Kakao JavaScript key has a project default in the server config. You can
override it in `.env`:

```text
KAKAO_JAVASCRIPT_KEY=<override_key>
KAKAO_REST_API_KEY=<directions_key>
OSRM_ROUTE_URL=https://router.project-osrm.org/route/v1/driving
```

The REST API key is used only by the server-side simulator to cache road route
geometry from Kakao Mobility Directions. If the key has an IP allowlist, add the
server/NAS public IP before expecting Kakao-based simulation. Until then, the
server can still use OSRM road geometry for demo movement.

In Kakao Developers, register every web origin that will open the control
screen. Useful early entries are:

```text
http://localhost:8080
http://127.0.0.1:8080
http://<NAS-LAN-IP>:18081
https://<NAS-domain>
```

If the origin is missing, Kakao's map SDK can return HTTP 403 and the control
screen will show a map-key/domain warning.

## Device Token

On first server start, the server creates:

```text
runtime-data/drivers.json
```

The default driver is:

```json
{
  "driverId": "demo-driver",
  "name": "Demo Driver",
  "vehicleNo": "SEOUL-12-3456",
  "token": "demo-token",
  "enabled": true
}
```

Change the token before real use.

## Admin Access

For sample/demo operation, admin API token checks are disabled by default:

```text
ADMIN_AUTH_REQUIRED=false
```

With this setting, the control screen works regardless of the admin token value
entered in the URL or prompt. Before real deployment, set
`ADMIN_AUTH_REQUIRED=true` and use a strong `ADMIN_TOKEN`.

## Test Simulator

The built-in simulator creates 10 test vehicles with fixed device tokens and
routes across Seoul, Incheon, Daejeon, Busan, Gwangju, Ulsan, Gangwon, Jeju,
and other regional hubs. It includes several freight vehicle types:

- `tractor-trailer`: 트레일러
- `cargo-truck`: 카고트럭
- `box-truck`: 탑차
- `van`: 용달차
- `refrigerated`: 냉동탑차
- `container`: 컨테이너
- `wingbody`: 윙바디

Each simulator tick updates latest positions through the same SSE stream used
by real Android uploads, so the control screen behaves like a live fleet map.

## API

Driver management:

```text
GET    /api/v1/drivers
POST   /api/v1/drivers
PATCH  /api/v1/drivers/:driverId
DELETE /api/v1/drivers/:driverId
```

Upload a location:

```powershell
$body = @{
  driverId = "demo-driver"
  vehicleNo = "SEOUL-12-3456"
  latitude = 37.5665
  longitude = 126.9780
  accuracy = 12
  speed = 42
  heading = 90
  cargoName = "전자부품"
  cargoQuantity = "36박스"
  cargoWeight = "1.2t"
  origin = "서울 상차지"
  destination = "평택 물류센터"
  destinationLatitude = 36.9921
  destinationLongitude = 127.1128
  routePath = @(
    @{ latitude = 37.5665; longitude = 126.9780 },
    @{ latitude = 37.33; longitude = 127.05 },
    @{ latitude = 36.9921; longitude = 127.1128 }
  )
  remainingDistanceKm = 74.5
  etaMinutes = 68
  estimatedArrivalAt = (Get-Date).AddMinutes(68).ToUniversalTime().ToString("o")
  recordedAt = (Get-Date).ToUniversalTime().ToString("o")
} | ConvertTo-Json -Depth 4

Invoke-RestMethod `
  -Uri "http://localhost:8080/api/v1/locations" `
  -Method Post `
  -Headers @{ "X-Device-Token" = "demo-token" } `
  -ContentType "application/json" `
  -Body $body
```

Read latest locations:

```text
GET /api/v1/locations/latest
```

Read history:

```text
GET /api/v1/locations/history?driverId=demo-driver&limit=200
```

Realtime events:

```text
GET /api/v1/events
```

## Android

Open `apps/android` in Android Studio and run the `app` module.

- Emulator server URL: `http://10.0.2.2:8080`
- Real phone server URL: `http://<NAS-or-PC-LAN-IP>:8080`
- Driver ID and device token: use the values from the web `기사` tab.

For production, use HTTPS and disable Android cleartext traffic.

## Operation Flow

1. Start the server on a PC or Synology NAS.
2. Open the control web screen.
3. Register a driver in the `기사` tab.
4. Copy that driver's token into the Android app.
5. Start tracking from the Android app.
6. Confirm the latest location in the `위치` tab.

## Next Steps

- Replace JSONL storage with PostgreSQL/PostGIS when history queries become
  important.
- Expand driver/vehicle management with search and editing.
- Add route playback and detailed location history filters.
- Add route, geofence, and delayed-reception alerts.
- Add Synology reverse proxy, HTTPS, and admin authentication for deployment.
