Accela Civic Platform integration setup

Accela's Civic Platform is widely used for permitting + code enforcement + citizen service requests. The adapter posts a **service request** via the v4 API for every routed report and PUTs it to `status: Closed` on resolution.

What you need:

1. **Register a Construct app** at the Accela developer portal (`developer.accela.com`). The app gets an **App ID** and an **App Token**.
2. **Get an access token.** Accela uses OAuth2 with multiple grant types. The simplest for a server-to-server integration is the password grant against your agency's instance. Use the dev portal's OAuth playground to issue an access token bound to your agency credentials.
3. **Pick the service request type** in your Accela agency configuration. The adapter maps Turtini categories to whatever value you pass for `type.value` (defaulting to the Turtini category name itself); ensure your agency has a matching type code or add a mapping rule on the Accela side.

Then in Turtini:

1. `/civicreports` → **Integrations** → **Accela** kind.
2. Fields:
- **API base** — leave the default `https://apis.accela.com` unless you have a private instance.
- **App ID** + **App Token** — from the developer portal.
- **Access Token** — from your OAuth exchange.
- **Agency name** — the lowercase short name of your Accela agency (drops into `x-accela-agency`).
3. Save.

What the adapter posts:
- `type.value` = Turtini category (e.g. `pothole`, `streetlight`)
- `description` = report description (falls back to title)
- `location.address.streetAddress` + `location.coordinates.{latitude,longitude}`
- `contact` block = reporter name / email / phone (or "Anonymous Reporter")
- `customFields` carries `turtini_report_id` + `turtini_jurisdiction`

On create, the returned `result.id` (or `result.customId`) is persisted as `externalCaseIds.accela`. On resolution, the adapter PUTs `status: { value: 'Closed' }` + `resolution` = your note.

Common gotchas:
- **Access token expired** = unlike Salesforce, the Accela adapter does NOT refresh tokens automatically (their refresh flow needs agency-side configuration we don't bundle). Refresh the token from your OAuth tooling and re-save the integration. Long-term tokens are doable via Accela's "long-lived token" admin setting if your security posture allows it.
- **Type not recognized** = your agency doesn't have a service-request type matching the Turtini category name. Add a mapping table on the Accela side, or write a small Accela rule that translates incoming `type.value` to your local SR type taxonomy.
- **Geo coords ignored** = your agency's SR template doesn't expose lat/lng. Address-based routing usually still works; talk to your Accela admin about exposing the coordinates field.