Cityworks (Trimble) integration setup

Cityworks Server AMS has the largest install base in municipal asset management. The adapter creates a Cityworks **ServiceRequest** for every report routed to your jurisdiction and updates it to **Resolved** when you close the report on Turtini's side.

What you need from your Cityworks admin:

1. **Server URL** — the base URL of your Cityworks Server install, e.g. `https://yourcity.cityworks.com`.
2. **Bearer token** — a long-lived API token issued by your Cityworks admin under **Designer → Security → API Tokens**. Give it permissions to create + update ServiceRequest records.
3. **ProblemSid** (optional) — the numeric SID of the Cityworks problem code you want incoming reports tagged with. Without this, the requests post with no problem code and you'll have to categorize them inside Cityworks.
4. **Agency domain** (optional) — for multi-tenant Cityworks installs, the agency identifier.

Then in Turtini:

1. `/civicreports` → **Integrations** tab.
2. Pick the jurisdiction.
3. Pick **Cityworks Server AMS** as the kind.
4. Paste the Server URL, bearer token, and optional problemSid / agencyDomain.
5. Check **Enabled**.
6. Save.

What the adapter sends:
- `Description` = report title + description
- `Address` + `X` + `Y` = reverse-geocoded address + lat/lng
- `Caller` block = reporter name / email / phone (anonymous reports stamp "Anonymous Reporter")
- `CustomFieldValues` carries `TurtiniReportId`, `TurtiniJurisdiction`, `TurtiniCategory` — handy for round-tripping.

On resolution, the adapter PUTs `Status: Resolved` + `ResolutionDesc` = whatever note you typed when you marked the report resolved.

The Cityworks `RequestId` returned on create is persisted on the Turtini report as `externalCaseIds.cityworks` so the resolution call can find the right record. Don't delete that field by hand — without it, resolution updates can't find their target.