Compliance Dashboard (COMP / HR_ADMIN)¶
Overview¶
The Compliance Dashboard is served at /dashboard for users with the COMP or HR_ADMIN role (routed through ApproverDashboard in client/src/pages/dashboards/ApproverDashboard.tsx). The same component is also shown to FI_USERs with is_approver flag set (Supervisors, Managers, CEOs). This document focuses on the COMP role experience.
The dashboard is a read-only overview optimized for declaration approval workflow — COMP officers review and act on declarations in their approval queue.
Page context: The dashboard page does not wrap in a PageEntityProvider — chatbot receives kind: 'none'.
Page Layout¶
Header¶
PageHeader component:
- Title: "Welcome, [User Name]" (from Keycloak name claim)
- Subtitle: "Review and approve Form 3A declarations"
The header does not include a "Start New Declaration" action button (unlike the RepDashboard — COMP users cannot create declarations from this page).
Metric Summary Cards (4 Cards)¶
A 2x2 grid (responsive to 4-column on large screens) with SummaryCard components:
| Card | Value Source | Color | On-Click Action |
|---|---|---|---|
| Awaiting My Action | myQueueItems.length |
Warning (amber) | Switches to "My Approval Queue" tab |
| Overdue | overdueItems.length (>5 days waiting) |
Danger (red) | Switches to "My Approval Queue" tab |
| Approved by Me | Count of steps where approver_user_id matches user AND status === 'approved' |
Success (green) | Switches to "All Applications" tab |
| Total Declarations | Non-draft declaration count | Info (blue) | Switches to "All Applications" tab |
Status Distribution Chart¶
A StatusDistributionChart component that visualizes declaration counts across all 9 statuses: Draft, Pending Review, Approved, Rejected, Revision Requested, Good, MAS Pending Review, MAS Approved, MAS Rejected.
Data computed from a DeclarationSummary object built by iterating all declarations and counting by declaration.status.
Overdue Alert Bar (Conditional)¶
Shown when overdueItems.length > 0. Red background bar with:
- AlertTriangle icon
- Message: "You have N overdue item(s) requiring attention"
- "View queue" link that switches to "My Approval Queue" tab
Tab Bar¶
Two tabs with counts:
| Tab Key | Label | Count Source |
|---|---|---|
my-queue |
My Approval Queue | Filtered pending instances where current step's approver_user_id matches current user |
all |
All Applications | All non-draft declarations |
My Approval Queue Tab (Default Active)¶
Table columns:
| Column | Content | Details |
|---|---|---|
| Rep Name | Rep name extracted from multiple sources | Source priority: declaration.rep_name > form_data.name_nric_passport > form_data.representativeName > form_data.name > fallback "Rep #N". Overdue items show a red dot indicator. |
| Rep ID | workflowInstance.rep_id |
Monospace font |
| Organisation | Extracted from form_data | Source priority: principal_company_name > organisationName > organisation |
| Current Step | Badge: "Step N of M" | Derived from currentStep.step_index + 1 and totalSteps |
| Time Waiting | TimeWaitingBadge component |
Four-tier color-coding: green (0-3d, plain badge), amber (4-7d, plain badge), amber with dot "Idle N d" (8-14d), red with dot "Stuck N d" (15d+). Computed from previous step's acted_at or declaration submitted_at. |
| Status | StatusBadge component |
From embedded workflowInstance.declaration.status or declaration object |
| Actions | "Review" button | Navigates to /declarations/:id/workflow |
Items are sorted by daysWaiting descending (most urgent first).
All Applications Tab¶
Table columns: ID, Rep ID, Status, Form Type, Days Pending, Updated, Actions
| Column | Content |
|---|---|
| ID | Declaration ID (monospace). Overdue indicator dot if >5 days. |
| Rep ID | declaration.rep_id (monospace) |
| Status | StatusBadge component |
| Form Type | formTypeLabel(): "Form 3A" / "Form 3B" / "Form 3C" |
| Days Pending | Color-coded badge: green (0-3d), amber (4-5d), red (6+d) |
| Updated | SG-locale date |
| Actions | "Review" button (if in user's queue) or "View" button (opens Form 3A view-only). Both rows also have a "Detail" button navigating to /declarations/:id. |
Items are sorted by days pending descending.
My Queue Computation¶
The myQueueItems array is built by:
- Filter all workflow instances to
status === 'pending' - For each, find the step at
current_step_indexthat also hasstatus === 'pending' - Build a
QueueItemwith: workflow instance, declaration (looked up bydeclaration_id), current step, total steps, and computeddaysWaiting - Filter to only items where
currentStep.approver_user_id === myNumericId(resolved by matching Keycloak UUID to Prisma user ID via the users list) - Sort by
daysWaitingdescending
daysWaiting is computed as: floor((now - referenceDate) / 86400000), where referenceDate is the previous step's acted_at (if exists), or the declaration's submitted_at, or the workflow instance's created_at (in priority order).
Overdue Detection¶
Overdue items are those in myQueueItems where daysWaiting > 5. This threshold matches the OVERDUE_THRESHOLD_DAYS = 5 constant used by the StatusBadge component and the AdminDashboard bottleneck detector. There is no separate configuration; 5 business days is the hard-coded standard across all dashboard components.
Data Sources¶
| Query | Purpose | Scope |
|---|---|---|
declarations (via useDeclarations) |
All declarations accessible to current user | Organisation-scoped by NestJS resolver |
workflowInstances (via useWorkflowInstances) |
All workflow instances | Organisation-scoped |
users (via useUsers) |
User list for ID resolution | Matches Keycloak UUID to Prisma numeric ID |
The dashboard does not use the platformMetrics query — that query is gated to @Roles("SYS_ADMIN", "ORG_ADMIN") and COMP users cannot access it. Do not fabricate platform-wide totals for COMP users.
What Is NOT on This Dashboard¶
The COMP dashboard does not display:
- Rep Health Distribution (GREEN/AMBER/RED) — this is on the AdminDashboard via AdminRepHealthCard, and only on the Rep Register page (/admin/rep-register) for COMP users
- Attestation Cycle Status — attestation cycles are managed at /admin/attestation, not on the main dashboard
- "Start New Declaration" button — this is exclusive to the Rep Dashboard (FI_USER/REP_USER)
- Platform-wide user/organisation counts — gated to SYS_ADMIN and ORG_ADMIN roles
How to Synthesize an Executive Snapshot¶
When the chatbot is asked to provide an executive summary of the COMP dashboard, it should:
- Identify urgent items: Count
myQueueItemsandoverdueItems— report exact numbers - Prioritize by staleness: The most urgent item is the one with the highest
daysWaitingvalue in the queue - Report pipeline health: Use the Status Distribution chart data to describe how many declarations are in each stage
- Call tools, not guess: The chatbot should call
get_rep_registerfor rep health data (not visible on this dashboard) and the attestation cycle query for cycle status (not visible on this dashboard) — these data points require separate API calls - Do NOT fabricate: If the user asks for data not shown on this dashboard (e.g., "how many green reps do we have"), direct them to
/admin/rep-registeror call the appropriate GraphQL query
Related Pages¶
/admin/attestation— Attestation cycle management (launch, track completion)/admin/rep-register— Rep health register with CMFAS + CPD R/A/G rollup/declarations/:id— Individual declaration detail with full form data and timeline/declarations/:id/workflow— Workflow approval page (where COMP acts on queued items)/dashboard(SYS_ADMIN/ORG_ADMIN) — AdminDashboard with platform metrics, rep health card, and bottleneck detection