Tutorials
Complaints, end to end
Every component kind in one working service: a resident photographs a pothole, files it over Telegram, and the city tracks it to a verified closure โ while the same spine proactively pulls complaints from news and social feeds, and an AI expert helps staff and vendors resolve them and find permanent fixes.
This is the capstone to Writing components. There you saw each kind alone; here they compose into one solution โ a pinned member-graph a city installs in one step. We use a real target: a complaints service for a large municipal tenant.
The use case
A resident sees a civic problem โ an overflowing bin, a broken streetlight, a flooded lane. They should be able to report it from where they already are (a chat app), with a photo, in their language; get a ticket; check status; and be asked to confirm when it's fixed. The city should see every complaint โ not only the ones filed directly, but the ones surfacing in the news and on social media โ on one queue, with the context staff need to act: the guidelines that apply, the vendor contract that covers that ward, the asset inventory, the terrain and drainage, and what happened the last ten times a complaint like this came in nearby.
The challenges this raises โ and the kind that answers each:
| Challenge | Kind |
|---|---|
| Let residents file + track from a channel we don't own | adapter (Telegram) |
| Don't miss complaints that never get filed | driver (news / social intake) |
| One queue, one record shape for all of them | a governed schema + the Inbox/Case spine |
| Find where complaints cluster; propose permanent fixes | engine (hotspots) |
| Help staff & vendors resolve each one, grounded in real context | skill + agent |
| A desk to work the queue | app |
| Install it all into a city in one step | solution |
The shape
Everything hangs off one governed record โ city.complaint โ and the universal Inbox & Case spine. Each kind only ever touches that spine through the broker; no component talks to another directly.
Build it, member by member
1 ยท Govern the vocabulary first. Before any code, propose the nouns and verbs this service needs โ city.complaint (the record), its status values, and the lifecycle verbs (file, assign, resolve, confirm-closed). Governance is shared, so reuse what exists (the generic Inbox/Case + lifecycle verbs) and propose only what's genuinely new. See Designing a schema and Designing a verb.
2 ยท The adapter โ file + track over Telegram. The confined Telegram adapter from Writing components โ Adapter. A message with a photo opens a city.complaint (the photo goes to the filestore, its digest onto the record); a message like "status NDMC-4821" reads the case back; and when work closes, the adapter asks the resident to confirm the fix โ their reply flips the case to closed-confirmed or re-opens it. The bot token is a per-tenant Vault secret; the admin clicks Activate in Settings โ Components.
3 ยท The driver โ proactive intake. A driver that polls news and social feeds (declared egress, key in Vault), extracts civic complaints, geocodes them to a ward, and writes them as city.complaint with source: news โ so a pothole trending online lands on the same queue as one filed by hand, deduped against existing open cases.
4 ยท The engine โ hotspots โ permanent fixes. An engine exposing complaint-hotspots: it reads all open and historical complaints, clusters them by location and category, joins terrain/drainage and asset inventory, and writes a ranked list of hotspots with a proposed permanent fix (a governance.recommendation) โ e.g. "re-grade this lane; 23 flooding complaints in 3 monsoons." It computes; it never decides.
5 ยท The skill + agent โ track to closure, help resolve. A skill per job (triage-and-route, draft-a-resolution-plan, check-against-guidelines) and an agent โ the Complaints Expert โ that bundles them under one persona. Each skill reads the case plus the grounding a resolver needs โ guidelines, the ward's vendor contract, asset inventory, terrain, hydrology, and the history of nearby complaints โ and proposes a cited next step for staff or the vendor. Every suggestion cites the records it stands on.
6 ยท The app โ the Complaints Desk. A sandboxed app showing the queue, each case's full context and the Expert's cited suggestions, with the action buttons (assign, resolve) that call the governed verbs as the signed-in officer. Residents need no app โ they're on Telegram.
Pin them into a solution
A solution is the member-graph plus the governed vocabulary it depends on. Declared once, it installs as a unit โ each member gets its per-tenant run token and grants, exactly the reads/writes/egress/secrets it certified.
# solution meta โ the pinned graph a city installs in one step
component_id: ds:<tenant>:solution/complaints
kind: solution
version: 0.1.0
provider: ds:<tenant>:developer
display_name: Citizen Complaints
members:
- ds:<tenant>:adapter/telegram-concierge # file + track + confirm closure
- ds:<tenant>:driver/complaints-intake # news + social โ city.complaint
- ds:<tenant>:engine/complaint-hotspots # clusters โ permanent-fix recommendations
- ds:<tenant>:agent/complaints-expert # bundles the resolution skills
- ds:<tenant>:app/complaints-desk # the officer's queue
requires_schemas: [city.complaint, governance.recommendation, platform.case, platform.inbox_item]
Install it into the city tenant; set the Telegram token in Settings โ Components; click Activate. The service is live โ residents file, the desk works the queue with the Expert's help, the hotspot engine runs on a schedule, and the intake driver keeps pulling.
Back to the challenges
- File + track from a channel we don't own โ the adapter, confined, token in Vault.
- Don't miss unfiled complaints โ the driver, feeding the same
city.complaintspine. - One queue, one shape โ the governed schema + Inbox/Case; every source normalises to it.
- Cluster + permanent fixes โ the engine, proposing cited
governance.recommendations. - Help staff & vendors resolve โ the agent + skills, grounded in guidelines, contracts, assets, terrain and history.
- A desk to work it โ the app, acting as the officer.
- Install in one step โ the solution.
Seven kinds, one record, one certified install โ and nothing in it can touch anything it didn't declare. That's the whole point of composing on AirawatOS: each piece is small and auditable, and the governance holds across all of them at once.
Build each member with Writing components; govern its vocabulary with Designing a schema / a verb; ship each with Build, test, publish.