# DroneFleet — CAD Install Guide (one page)

Wire DroneFleet's drone-as-first-responder into your CAD in **3 steps**: provision a
credential, drop one launch URL into your drone-deploy action, test. Full reference:
[`DroneFleet-DFR-API.md`](DroneFleet-DFR-API.md).

**API base URL:** `https://dronefleet-api.azurewebsites.net`
(everything below is relative to this — swap in your own if self-hosted.)

**Aircraft:** DroneFleet supports **MAVLink-compatible autopilots only** (ArduPilot /
PX4 / Pixhawk-class, including Blue UAS / NDAA airframes built on them). Non-MAVLink
drones (DJI consumer, or vendor-SDK-only platforms like Skydio / BRINC) need a separate
vendor adapter.

---

## Step 1 — Provision a Client ID + Secret (one-time)

An **organization admin** mints one credential and gives it to you. It's returned
**once** — store the `clientSecret` in your CAD's secure config.

**PowerShell**
```powershell
$base = 'https://dronefleet-api.azurewebsites.net/api/v1'
$admin = @{ Authorization = 'Bearer ' + (Invoke-RestMethod "$base/auth/login" -Method Post `
  -ContentType 'application/json' -Body '{"email":"admin@dronefleet.dev","password":"Passw0rd!"}').token }
Invoke-RestMethod "$base/api-keys" -Method Post -Headers $admin -ContentType 'application/json' `
  -Body '{"label":"City CAD - DFR","scopes":"*"}'
# → clientId  = dfc_....   (public — safe to store/log)
# → clientSecret = dfk_.... (SECRET — shown once, store securely)
```

**curl**
```bash
TOKEN=$(curl -s https://dronefleet-api.azurewebsites.net/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@dronefleet.dev","password":"Passw0rd!"}' | jq -r .token)
curl -s -X POST https://dronefleet-api.azurewebsites.net/api/v1/api-keys \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"label":"City CAD - DFR","scopes":"*"}'
```

> Replace the demo `admin@dronefleet.dev` / `Passw0rd!` with your real org-admin login.
> Store `clientId` + `clientSecret` in CAD config (e.g. `DroneFleet:ClientId` /
> `DroneFleet:ClientSecret`).

---

## Step 2 — Wire your drone-deploy action

When the dispatcher hits **Deploy Drone** on an incident, open DroneFleet's console
(served by the API — same-origin, **no CORS setup**). Substitute your credential + the
incident's fields:

```js
const base = "https://dronefleet-api.azurewebsites.net";
const p = new URLSearchParams({
  clientId:     "dfc_...",          // from Step 1
  clientSecret: "dfk_...",          // from Step 1  (server-side render or a short-lived proxy is safest)
  source:  "CFS",                   // "CFS" (call-for-service) or "UNIT"
  caseNo:  incident.caseNumber,
  label:   incident.type,           // e.g. "Structure fire"
  addr:    incident.address,        // e.g. "123 Main St"
  lat:     incident.lat,            // incident location (map centers here)
  lon:     incident.lon,
  priority: incident.priority,      // 1 | 2 | 3
  callsign: incident.callsign,
  vehicleId: incident.droneId       // optional — else auto-selects an available fleet drone
});
window.open(`${base}/console?${p}`, "droneOps", "width=1440,height=900");
```

This opens the DroneFleet ground-control view (the same one the DroneFleet dispatch map
uses), which connects with your credential and tracks the drone live. Prefer embedding?
Use an `<iframe src="…/console?…">` in your incident view instead of `window.open`.

To also **deploy** the mission, your CAD calls `POST /api/v1/missions` + `/start`
(guide §5.2) with the CAD credential — before or while opening the console.

**Launch params**

| Param | Meaning |
|---|---|
| `clientId` + `clientSecret` | your installed credential (Step 1) |
| `source` | `CFS` or `UNIT` |
| `caseNo · label · addr · priority · callsign` | shown in the console header |
| `lat` + `lon` | incident location (map centers here) |
| `vehicleId` | which fleet drone to track (optional) |

The console does the rest: live GPS map + drone tracking, camera-footprint ⇄ video view,
altitude/speed/heading/battery, scene target-ID, and flight/payload controls.

---

## Step 3 — Test it

Paste a filled-in URL into a browser:

```
https://dronefleet-api.azurewebsites.net/console?clientId=dfc_...&clientSecret=dfk_...&source=CFS&caseNo=TEST-1&label=Test%20call&addr=123%20Main%20St&lat=33.4405&lon=-86.789&priority=1
```

You should see the console connect (**LIVE** badge) and start tracking the fleet drone.
Verify the credential from the command line:

```powershell
Invoke-RestMethod "$base/vehicles" -Headers @{ 'X-Api-Key'='dfc_...'; 'X-Api-Secret'='dfk_...' }
```

---

## Before you go live

- **Set your operating area** (geofence) so waypoints outside your jurisdiction are
  rejected. This is an **admin** action (use the org-admin login from Step 1, not the
  CAD's `*` credential — that can deploy/monitor but not change config). One call — box
  or polygon:
  ```powershell
  # $admin = the Bearer headers from Step 1
  Invoke-RestMethod "$base/config/geofence" -Method Put -Headers $admin -ContentType 'application/json' `
    -Body '{"minLon":-86.95,"minLat":33.30,"maxLon":-86.55,"maxLat":33.60,"maxAltM":120,"label":"City of ABC"}'
  ```
  Or use the visual tool [`samples/geofence-config.html`](samples/geofence-config.html).
  Defaults to a demo area (Vestavia Hills, AL) until you set your own — see guide §5.7.

- **Rotate** the secret on a schedule — same client id (org admin):
  `POST /api/v1/api-keys/{id}/rotate-secret`
- **Revoke** a compromised credential (org admin): `DELETE /api/v1/api-keys/{id}`
- **Receive detections in CAD** without polling: subscribe a webhook for
  `target.detected` — guide §7. (Creating a webhook works with the CAD's `*` credential.)

---

## Auth cheat-sheet

Every API call authenticates one of these ways (all equivalent):

```
Authorization: Basic base64("<clientId>:<clientSecret>")      # HTTP Basic
X-Api-Key: <clientId>   +   X-Api-Secret: <clientSecret>       # two headers
```

Questions / full endpoint reference → [`DroneFleet-DFR-API.md`](DroneFleet-DFR-API.md)
(auth §2, deploy lifecycle §3, geofence §5.7, console embed §5.8, webhooks §7).
