> For the complete documentation index, see [llms.txt](https://docs.digit.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.digit.org/complaints-management/cms-v2.11/deploy/configure/dashboard.md).

# Dashboard

## Overview

Everything described on this page is live MDMS data. You change it with the standard `mdms-v2` record APIs — no rebuild and no redeploy.

Anything not listed here (query planning, row-scope/ABAC enforcement, the frontend module itself) is application code, not configuration. The one exception is the complaint row-scope policy, which is configuration and is covered in [Steps](#steps).

#### What ships on a fresh `tenant_bootstrap`

<table><thead><tr><th width="213.61328125">MDMS record</th><th>What it is</th></tr></thead><tbody><tr><td><code>dss.KpiDefinition</code></td><td><a href="https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/ansible/nairobi-mdms/mdms/dss/KpiDefinition.json">40 KPI tile definitions</a> (query, visualisation, params)</td></tr><tr><td><code>dss.DashboardPack</code></td><td>2 packs: <code>supervisor-default</code> (employee dashboard) and <code>public-default</code> (public curated dashboard)</td></tr><tr><td><code>dss.DashboardConfig</code></td><td>Number-format display config only — no role list lives here</td></tr></tbody></table>

#### Who gets access, and to what

Access is granted in **tiers**. Each tier is an action, and roles hold actions:

<table><thead><tr><th width="222.484375">Grant</th><th width="220.63671875">Purpose</th><th>Held by (as shipped)</th></tr></thead><tbody><tr><td>Nav action <code>4557</code></td><td>Dashboard <strong>sidebar</strong> entry</td><td>SUPERVISOR, GRO, DGRO, SUPERUSER</td></tr><tr><td>Capability actions <code>2640–2645</code> (<code>_access</code>, <code>_query</code>, <code>packs</code>, <code>catalog/_search</code>, <code>_schema</code>, <code>config/_refresh</code>)</td><td>Base dashboard usage</td><td>Same as above</td></tr><tr><td><code>2646</code> <code>capabilities/officer</code></td><td>Officer-tier KPIs</td><td>PGR_SUPERVISOR, PGR_ADMIN, SUPERUSER, SUPERVISOR, MDMS_ADMIN, HRMS_ADMIN</td></tr><tr><td><code>2647</code> <code>capabilities/reports</code></td><td>Reports-tier KPIs</td><td>PGR_VIEWER, TICKET_REPORT_VIEWER</td></tr><tr><td><code>2648</code> <code>capabilities/reports-extended</code></td><td>Most-restricted tier</td><td>TICKET_REPORT_VIEWER</td></tr></tbody></table>

Two things follow from the table:

* **Tile visibility is per tier, not per role.** The four roles with a sidebar entry do not all see the same dashboard:

  | Role                  | Tiers held     | Default KPIs visible |
  | --------------------- | -------------- | -------------------- |
  | GRO, DGRO             | Base           | 27 of 40             |
  | SUPERVISOR, SUPERUSER | Base + officer | 30 of 40             |
* **The sidebar entry and the capability tiers are granted separately.** Some roles hold a capability tier (`2646`–`2648`) without holding a nav action `4557`.

#### How a tile picks its tier

Each `dss.KpiDefinition` and `dss.DashboardPack` record names the tier it needs in a `requiredActionUrl` field:

```json
"requiredActionUrl": "/pgr-services/v2/analytics/capabilities/officer"
```

A KPI marked `"public": true` skips authorisation entirely and appears on the public dashboard.

#### Department and jurisdiction visibility is inherited, not separate

The dashboard has no JBAC record of its own. It deliberately reuses the **complaint row-scope policy**, so dashboard aggregates can never expose complaints the same user cannot see in search. To change it, edit that shared policy — see [Set department and jurisdiction visibility](#set-department-and-jurisdiction-visibility).

#### The home-screen card does not ship by default

Action `4557` gates only the **sidebar** entry. The employee **home-screen card** is a separate thing: a `"Dashboard"` row in `tenant.citymodule`, which `tenant_bootstrap` copies from the source tenant (as in the bomet deployment).

The base `default-data-handler` seed lists only `Workbench`, `PGR` and `HRMS` — no `Dashboard` row. So a fresh install gets the sidebar entry but no home-screen card. This is the same class of gap as #1408, which was fixed for `KpiDefinition` and `DashboardPack` but not extended here. Use the code below to add the card:

```
{ "code": "Dashboard", "order": 14, "active": true, "module": "Dashboard", "tenants": [{ "code": "<tenantId>" }] }
```

against `tenant.citymodule` (`POST /mdms-v2/v2/_create/tenant.citymodule`) if you want the card now.

## Steps

#### Quick reference

Full field-by-field shapes, each with a real example, are in [`95-mdms-schema-reference.md`](https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/dashboard/dashboard-rbac-design/95-mdms-schema-reference.md).

<table><thead><tr><th width="204.76171875">To...</th><th width="274.01953125">Call</th><th>Shape</th></tr></thead><tbody><tr><td>Add or edit a KPI</td><td><code>_create</code> / <code>_update</code> <code>dss.KpiDefinition</code> (<code>_update</code> needs the record's <code>id</code>)</td><td><a href="https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/dashboard/dashboard-rbac-design/95-mdms-schema-reference.md#dsskpidefinition"> KpiDefinition</a></td></tr><tr><td>Change a pack's tiles or layout</td><td><code>_create</code> / <code>_update</code> <code>dss.DashboardPack</code></td><td><a href="https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/dashboard/dashboard-rbac-design/95-mdms-schema-reference.md#dssdashboardpack">DashboardPack</a></td></tr><tr><td>Change number formatting</td><td><code>_create</code> / <code>_update</code> <code>dss.DashboardConfig</code></td><td><a href="https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/dashboard/dashboard-rbac-design/95-mdms-schema-reference.md#dssdashboardconfig">DashboardConfig</a></td></tr><tr><td>Grant or revoke a capability tier</td><td><code>_create</code> <code>ACCESSCONTROL-ROLEACTIONS.roleactions</code></td><td><a href="https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/dashboard/dashboard-rbac-design/95-mdms-schema-reference.md#accesscontrol-roleactionsroleactions">ROLEACTIONS</a></td></tr><tr><td>Add a new capability tier</td><td><code>_create</code> <code>ACCESSCONTROL-ACTIONS-TEST.actions-test</code></td><td><a href="https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/dashboard/dashboard-rbac-design/95-mdms-schema-reference.md#accesscontrol-actions-testactions-test">ACTIONS-TEST</a></td></tr><tr><td>Change labels</td><td><code>_upsert</code> the message key, then <code>POST /localization/messages/cache-bust</code></td><td>—</td></tr></tbody></table>

#### Grant or revoke a capability tier

1. `_create` a record in `ACCESSCONTROL-ROLEACTIONS.roleactions` for the role and action.
2. To **revoke**, deactivate the existing record.

There is no `_update` for roleactions — the key is `{rolecode, actionid}`.

#### Add a new capability tier

1. Create a new action in `ACCESSCONTROL-ACTIONS-TEST.actions-test` with the URL `/pgr-services/v2/analytics/capabilities/<name>`.
2. Grant that action to the roles that need it, via `roleactions`.
3. Point the `requiredActionUrl` of the relevant KPI or pack at the new URL.

#### Add the dashboard card to the employee home screen

`POST /mdms-v2/v2/_create/tenant.citymodule` with:

```json
{ "code": "Dashboard", "order": 14, "active": true, "module": "Dashboard", "tenants": [{ "code": "<tenantId>" }] }
```

#### Set department and jurisdiction visibility

1. In `ACCESSCONTROL-ACTIONS-TEST.actions-test`, find the tenant's action with `data.id: 2008` and `data.url: "/pgr-services/v2/request/_search"`.
2. Update `data.resource.complaint.scope.roleScopes` using the standard MDMS v2 `_update` API.
3. Preserve the rest of the action record, including its MDMS `uniqueIdentifier` and any `attributes` rules.

**Rules**

* Set `department` and `jurisdiction` independently, to either `OWN` or `ALL`.
* If none of a user's roles sets a value for an axis, the policy falls back to `default`.
* `OWN` requires a current HRMS assignment for that axis. A missing assignment returns no rows.

**Example** — an LME is limited to their active HRMS department and jurisdiction, while a supervisor sees every jurisdiction within their own department:

```json
"scope": {
  "axes": ["department", "jurisdiction"],
  "roleScopes": {
    "PGR_LME": { "department": "OWN", "jurisdiction": "OWN" },
    "SUPERVISOR": { "department": "OWN", "jurisdiction": "ALL" }
  },
  "default": { "department": "OWN", "jurisdiction": "OWN" }
}
```

**Before you change this**

* This is a shared policy: it also changes complaint search and inbox visibility.
* Policy reads are cached in `pgr-services` for up to 15 minutes. Restart the service only if the change must take effect immediately.
* For the full behaviour and rollout guidance, see [Jurisdiction-Based Access Control.](/complaints-management/cms-v2.11/release-notes/jurisdiction-access-control.md)

#### If you edit the Ansible seed files instead of a live tenant

Regenerate `digit-mcp/src/tools/dashboard-catalog-seed.ts` by running `digit-mcp/scripts/gen-dashboard-catalog.mjs`. CI fails when the seed JSON and the generated catalogue drift.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.digit.org/complaints-management/cms-v2.11/deploy/configure/dashboard.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
