Use when setting up a new city or tenant on DIGIT platform, onboarding a municipality, creating employees, or configuring PGR complaint types for a new area.
Hard-gated 10-step procedure for setting up a new city on the DIGIT PGR platform. Every step has a verification gate. Do NOT proceed past a gate that fails.
NO PGR OPERATIONS WITHOUT TENANT EMPLOYEE AUTHENTICATION FIRST.
If you are logged in as ADMIN (loginTenantId = "pg"), PGR calls on any non-pg tenant WILL fail with "User is not authorized". You MUST authenticate as a tenant employee (Step 6) before Steps 7-10.
digraph tenant_setup {
rankdir=TB
node [shape=box style=rounded]
configure [label="Step 0: configure + enable_tools"]
bootstrap [label="Step 1: tenant_bootstrap"]
gate1 [shape=diamond label="Schemas exist\nat target root?"]
register [label="Step 2: Register tenant in MDMS"]
boundaries [label="Step 3: Create boundaries"]
gate3 [shape=diamond label="Boundaries\nvalidated?"]
workflow [label="Step 4: Register PGR workflow"]
gate4 [shape=diamond label="Workflow exists\nor created?"]
servicedefs [label="Step 5: Create service definitions\n(root + city)"]
employees [label="Step 6: Create employees\n(GRO + LME)"]
gate6 [shape=diamond label="loginTenantId\n= target root?"]
auth [label="Step 7: Authenticate as\ntenant employee"]
pgr_create [label="Step 8: File test complaint"]
pgr_assign [label="Step 9: Assign + Resolve"]
pgr_rate [label="Step 10: Rate + Close"]
done [label="DONE" shape=doublecircle]
fail [label="STOP\nFix before continuing" shape=octagon style=filled fillcolor="#ffcccc"]
configure -> bootstrap
bootstrap -> gate1
gate1 -> register [label="yes"]
gate1 -> fail [label="no"]
register -> boundaries
boundaries -> gate3
gate3 -> workflow [label="yes"]
gate3 -> fail [label="no"]
workflow -> gate4
gate4 -> servicedefs [label="yes"]
gate4 -> fail [label="no"]
servicedefs -> employees
employees -> gate6
gate6 -> auth [label="yes"]
gate6 -> fail [label="no\n(mobile conflict)"]
auth -> pgr_create
pgr_create -> pgr_assign
pgr_assign -> pgr_rate
pgr_rate -> done
}
One question at a time. Hide ALL technical complexity. WAIT for the user to answer before proceeding.
Phase 1 — Identity (derive tenant codes automatically)
Phase 2 — Services
Phase 3 — Staff
Phase 4 — Done
CRITICAL: Never mention tenants, MDMS, boundary hierarchies, service definitions, localization keys, employee codes, or any technical term. If setup fails, say "Let me try a different approach" and handle silently.
configure(environment="chakshu-digit")
enable_tools(enable=["mdms","boundary","masters","employees","pgr","admin","idgen"])
tenant_bootstrap(target_tenant="<root>", source_tenant="pg")
GATE: Call mdms_schema_search(tenant_id="<root>"). Must return schemas. If 0 schemas → STOP, bootstrap failed.
mdms_create(
tenant_id = "<root>",
schema_code = "tenant.tenants",
unique_identifier = "<root>.<city>",
data = {
code: "<root>.<city>", name: "<City Name>",
description: "...", type: "CITY",
city: { name, localName, districtCode, districtName,
regionName, ulbGrade, latitude, longitude, code }
}
)
GATE: Call validate_tenant(tenant_id="<root>.<city>"). Must return the tenant.
Use real locality names from boundary data sources (see below).
boundary_create(
tenant_id = "<root>.<city>",
hierarchy_definition = ["State", "District", "City", "Locality"],
boundaries = [
{ code: "<ST>", type: "State" },
{ code: "<ST>_<DIST>", type: "District", parent: "<ST>" },
{ code: "<DIST>_CITY", type: "City", parent: "<ST>_<DIST>" },
{ code: "<PREFIX>_<LOC>", type: "Locality", parent: "<DIST>_CITY" },
...
]
)
GATE: Call validate_boundary(tenant_id="<root>.<city>"). Must show localities under the city.
Only needed once per state root. City tenants inherit.
workflow_create(tenant_id="<root>.<city>", copy_from_tenant="pg.citya")
If response says skipped: ["PGR"] — workflow already exists, proceed.
GATE: Call workflow_business_services(tenant_id="<root>", business_services=["PGR"]). Must return the PGR state machine.
Must register at BOTH state root AND city level.
# 5a — State root (required for pgr_create to resolve service codes)
mdms_create(
tenant_id = "<root>",
schema_code = "RAINMAKER-PGR.ServiceDefs",
unique_identifier = "<ServiceCode>",
data = { serviceCode, name, keywords: "comma,separated", menuPath: "<Category>",
department, slaHours, active: true }
)
# 5b — City level (required for city-scoped filtering)
mdms_create(
tenant_id = "<root>.<city>",
schema_code = "RAINMAKER-PGR.ServiceDefs",
unique_identifier = "<ServiceCode>",
data = { serviceCode, name, keywords: "...", department, slaHours, active: true }
)
Field rules:
keywords must be a plain string (e.g. "road,pothole,damaged"), not a JSON arraymenuPathName or description — schema rejects themmenuPath (no "Name") at root level onlyGATE: Call validate_complaint_types(tenant_id="<root>.<city>"). Must list all created service codes.
employee_create(
tenant_id = "<root>.<city>",
name, mobile_number,
roles = [{ code: "EMPLOYEE", name: "Employee" }, { code: "GRO", name: "Grievance Routing Officer" }],
department, designation,
jurisdiction_boundary_type = "City",
jurisdiction_boundary = "<DIST>_CITY"
)
[EMPLOYEE, GRO][EMPLOYEE, PGR_LME]EMP-CBE-000058) for loginGATE: Call validate_employees(tenant_id="<root>.<city>", required_roles=["GRO","PGR_LME"]). Must find both roles.
configure(
username = "<EMPLOYEE_CODE>",
password = "eGov@123",
tenant_id = "<root>.<city>"
)
GATE: Response must show loginTenantId = "<root>" (NOT "pg"). If it shows "pg", the employee's user was linked to an existing pg user (mobile number conflict). Try a different employee or use a unique mobile number.
pgr_create(
tenant_id = "<root>.<city>",
service_code = "<ServiceCode>",
description = "Test complaint for verification",
address = { locality: { code: "<LOCALITY_CODE>" }, city: "<City>" },
citizen_name = "Test Citizen",
citizen_mobile = "<unique 10-digit>"
)
GATE: Call pgr_search(tenant_id="<root>.<city>"). Must return the complaint with status PENDINGFORASSIGNMENT.
pgr_update(action="ASSIGN", service_request_id="...", tenant_id="<root>.<city>")
Do NOT pass assignees — explicit UUID assignment fails. Let PGR auto-route.
Then authenticate as LME and resolve:
configure(username="<LME_CODE>", password="eGov@123", tenant_id="<root>.<city>")
pgr_update(action="RESOLVE", service_request_id="...", tenant_id="<root>.<city>")
GATE: pgr_search must show status RESOLVED.
configure(username="<citizen_mobile>", password="eGov@123", tenant_id="<root>.<city>")
pgr_update(action="RATE", service_request_id="...", tenant_id="<root>.<city>", rating=5)
GATE: pgr_search must show status CLOSEDAFTERRESOLUTION. Setup complete.
https://overpass-api.de/api/interpretercurl -sL "https://overpass-api.de/api/interpreter" \
--data-urlencode 'data=[out:json][timeout:30];
area["name"="<CityName>"]["boundary"="administrative"]->.city;
(node["place"~"suburb|neighbourhood|quarter"](area.city););
out tags;' \
| python3 -c "
import json, sys
data = json.load(sys.stdin)
names = sorted(set(el['tags']['name'] for el in data['elements'] if 'name' in el.get('tags',{})))
for n in names: print(n)
print('Total:', len(names))
"
https://raw.githubusercontent.com/sab99r/Indian-States-And-Districts/master/states-and-districts.json| Need | Source |
|---|---|
| Districts for a state | sab99r GitHub |
| Localities/suburbs in a city | Overpass API |
| Ward boundaries with geometry | datameet (check availability) |
| Official government data | data.gov.in or Bhuvan |
These are things you might be tempted to skip. DO NOT.
| Rationalization | Why it's wrong | What to do instead |
|---|---|---|
| "I'll skip bootstrap, schemas probably exist" | Without bootstrap, mdms_create fails with "Schema definition not found" | Always run tenant_bootstrap for new roots |
| "I'll use ADMIN user for PGR operations" | ADMIN's roles are scoped to pg. PGR on other tenants returns 403 | Authenticate as tenant employee (Step 7) |
| "I'll create service defs only at root" | City-level filtering won't work, and some queries need city-level records | Create at BOTH root and city level |
| "I'll pass assignees to pgr_update" | Explicit UUID assignment fails with tracer exception | Omit assignees, let PGR auto-route |
| "I'll include CITIZEN role in employee" | HRMS rejects CITIZEN and CSR roles for employees | Only EMPLOYEE + specific PGR roles |
| "Mobile number conflicts don't matter" | loginTenantId gets set to wrong root, all PGR ops fail | Use unique mobile numbers per tenant |
| "I'll skip the verification gate" | Silent failures propagate — a missing workflow causes pgr_create to 500 | Run every gate check |
If you see any of these, STOP and investigate:
loginTenantId doesn't match the target tenant rootpgr_create returns "Failed to parse mdms response for service"employee_create returns 400 with "userName=null"workflow_create returns error (not "skipped")validate_boundary shows 0 localitiesSee error-reference.md for the full error → fix table.
chakshu-digit | URL: https://api.egov.theflywheel.intenant | Login tenant: pg (ADMIN only)configure first, then enable_tools for required groups.