# REST API Reference — IoT SmartBin

Base URL: `http://localhost:3001/api/v1`

---

## Tenants

### GET /tenants
List all tenants.

**Response:**
```json
[
  { "tenant_id": "tenantA", "name": "PT Bersih Sejahtera" }
]
```

---

## Sites

### GET /tenants/:tenantId/sites
List all sites for a tenant.

**Response:**
```json
[
  {
    "site_id": "jakarta-utara",
    "tenant_id": "tenantA",
    "name": "Jakarta Utara",
    "lat": -6.12,
    "lon": 106.92
  }
]
```

---

## Bins (Devices)

### GET /tenants/:tenantId/sites/:siteId/bins
List all bins at a site.

**Query params:**
- `status` (optional): filter by status (`FULL`, `MEDIUM`, `EMPTY`)
- `page` (optional): page number (default 1)
- `limit` (optional): items per page (default 50, max 200)

**Response:**
```json
{
  "data": [
    {
      "device_id": "bin-001",
      "tenant_id": "tenantA",
      "site_id": "jakarta-utara",
      "firmware_version": "1.0.0",
      "last_seen": "2025-01-15T10:30:00Z",
      "status": "FULL",
      "lat": -6.12345,
      "lon": 106.98765
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 120
  }
}
```

### GET /tenants/:tenantId/sites/:siteId/bins/:deviceId/latest
Get latest telemetry for a specific bin.

**Response:**
```json
{
  "device_id": "bin-001",
  "ts": "2025-01-15T10:30:00Z",
  "us_cm": 12.3,
  "ir_cm": 14.8,
  "ir_mv": 1860,
  "fill_percent": 82,
  "status": "FULL",
  "rssi": -55,
  "battery": 3.90
}
```

### GET /tenants/:tenantId/sites/:siteId/bins/:deviceId/history
Get telemetry history for a bin.

**Query params:**
- `from` (required): ISO timestamp
- `to` (required): ISO timestamp
- `limit` (optional): max rows (default 500)

**Response:**
```json
{
  "data": [
    {
      "ts": "2025-01-15T10:30:00Z",
      "us_cm": 12.3,
      "ir_cm": 14.8,
      "ir_mv": 1860,
      "fill_percent": 82,
      "status": "FULL",
      "rssi": -55,
      "battery": 3.90
    }
  ],
  "count": 100
}
```

---

## Routes

### POST /tenants/:tenantId/routes/optimal
(Served by route-service on port 3002)

See [docs/routes.md](routes.md) for full details.

---

## Socket.IO (Realtime)

**Namespace:** `/realtime`
**Port:** 3001 (same as api-service)

### Events

#### Client → Server
- `join:site` — Join a site room
  ```json
  { "tenantId": "tenantA", "siteId": "jakarta-utara" }
  ```
- `leave:site` — Leave a site room
  ```json
  { "tenantId": "tenantA", "siteId": "jakarta-utara" }
  ```

#### Server → Client
- `telemetry:latest` — New telemetry data for any bin in the joined site
  ```json
  {
    "deviceId": "bin-001",
    "ts": 1700000000,
    "fill_percent": 82,
    "status": "FULL",
    "us_cm": 12.3,
    "rssi": -55,
    "battery": 3.90
  }
  ```
- `status:change` — Bin status changed
  ```json
  {
    "deviceId": "bin-001",
    "status": "FULL",
    "fill_percent": 82
  }
  ```
- `availability:change` — Device online/offline
  ```json
  {
    "deviceId": "bin-001",
    "availability": "online"
  }
  ```

### Room Model
- Room key: `{tenantId}:{siteId}` (e.g., `tenantA:jakarta-utara`)
- Client only receives events for bins in their joined site(s)
- This prevents broadcasting all 10k device updates to all clients
