Dashboards and Reporting
Audience: Manager, Unit Leaders
Page Type: How-To Guide
Phase: Cross-Phase
Duration: 30 minutes
Goal
Using Dashboards to:
- ✅ See strategic cycle progress
- ✅ Check OKR scores and health status
- ✅ Track unit performance
- ✅ Make data-driven decisions
Dashboard Types
1. Unit Leader Panel
Who: SUPER_ADMIN, ADMIN, STRATEGY_MANAGER, TEAM_LEAD, or any unit leader (including ROOT)
Access: /dashboard → Unit Leader Panel tab
Data Scope: The leader's own unit's direct objectives + first-level child units.
ROOT-level leaders and unit leaders see the same panel. The difference is scope: ROOT sees root objectives plus first-level units; a unit leader sees only their unit and child units.
Metric Calculations
A. Health Score (Pace-Based Health — 0-100)
For each objective, the same formula used on the OKR Cycles page "Health %" is applied:
timeProgress = elapsed / totalDuration (0-1 range)
If elapsed ≤ 0 → 100 (cycle not started)
If timeProgress < 0.1 → 100 (grace period — first 10% of time)
If timeProgress > 1 → clamp to 1 (cycle ended)
expectedProgress = timeProgress × 100
healthScore = (currentProgress / expectedProgress) × 100
result = clamp(0, 100, round(healthScore))
currentProgress = Weighted average of objective's KRs:
objProgress = Σ(kr.progress × kr.weight) / Σ(kr.weight)
If KR weight is missing, type-based fallback: METRIC = 1, MILESTONE = 0.8, TASK = 0.5.
B. Weighted Progress
Per unit, the weighted average of that unit's direct objectives:
weightedProgress = Σ(objProgress × obj.weight) / Σ(obj.weight)
Only objectives in active OKR cycles are included.
C. Weighted Health
Per unit, the weighted health score average of direct objectives:
weightedHealth = Σ(healthScore × obj.weight) / Σ(obj.weight)
D. Child Units Table
The leader's unit's first-level child units are shown in a separate table. Each child unit displays the same metrics:
| Column | Description |
|---|---|
| Unit | Child unit name and type |
| Objective Count | Number of objectives directly belonging to that unit |
| Weighted Progress | KR-weighted average progress |
| Health | Pace-based health score (0-100%) |
Sub-units of child units are not shown (first-level only).
Data Flow
StrategicCycle (ACTIVE)
└─ OkrCycle (PLANNING | IN_APPROVAL | ACTIVE | REVIEW)
└─ OkrObjective (unit's direct objectives)
└─ KeyResults (progress × weight → pace health)
2. Strategy Compass
Who: SUPER_ADMIN, ADMIN, STRATEGY_MANAGER
Access: /dashboard → Strategy Compass tab
Purpose: Answers the question "Is the ship on course?" Shows target vs. actual comparisons for KPIs under strategic themes; deviations are immediately visible.
GROUP_ADMIN, TEAM_LEAD (except ROOT leader) and MEMBER cannot see this panel.
Data Scope
All strategic themes in the active strategic cycle and the latest measurement data for their linked KPIs are evaluated.
Metric Calculations
A. KPI Gap Calculation (Gap %)
The gap is calculated based on each KPI's direction (betterDirection):
HIGHER_IS_BETTER → gapPercent = (actual - target) / target × 100
LOWER_IS_BETTER → gapPercent = (target - actual) / target × 100
Positive gap = above target (good), negative gap = below target (bad).
B. KPI Status
| Gap % | Status | Meaning |
|---|---|---|
| ≥ -10% | ON_TRACK | Near or above target |
| -10% to -25% | AT_RISK | Deviation starting, intervention needed |
| < -25% | OFF_TRACK | Serious deviation, urgent action needed |
| No data | NO_DATA | No measurement data entered |
C. Theme KPI Health
Average of status scores for KPIs with data under a theme:
Score: ON_TRACK = 100, AT_RISK = 50, OFF_TRACK = 0
themeKpiHealth = Σ(score) / kpisWithDataCount
D. Theme Combined Health
Weighted combination of KPI health and OKR objective health (pace-based):
combinedHealth = themeKpiHealth × 0.7 + objectiveHealth × 0.3
Objective Health is not raw progress — it’s a pace-based health score that accounts for time elapsed:
timeProgress = elapsed / totalDuration (0-1 range, from OKR cycle start/end)
If elapsed ≤ 0 → 100 (cycle not started)
If timeProgress < 0.1 → 100 (grace period — first 10% of time)
If timeProgress > 1 → clamp to 1 (cycle ended)
expectedProgress = timeProgress × 100
objHealth = (currentProgress / expectedProgress) × 100
result = clamp(0, 100, round(objHealth))
currentProgress = Σ(kr.progress × kr.weight) / Σ(kr.weight)
Theme-level objective health = average of all linked objectives' objHealth.
KPI weight (70%) is higher because this panel is primarily for KPI-based gap analysis.
If only KPI data exists, only KPI health is used. If only objectives exist, only objective progress is used.
E. Overall Health
Weighted average across all themes:
overallHealth = Σ(theme.combinedHealth × theme.weight) / Σ(theme.weight)
User Interface
| Section | Content |
|---|---|
| Strategic Cycle | Active cycle name, time progress, days remaining |
| Overall Health | Weighted overall health percentage |
| KPI Summary | Total / On Track / At Risk / Off Track KPI counts |
| Unit Objective Health | ROOT unit and first-level departments' average objective health (progress-circle cards) |
| Theme Health Map | Scatter chart: X=KPI Health, Y=Objective Health, circle size=theme weight, color=theme color |
| Theme Cards | Per theme: color, weight, status distribution, combined health |
| KPI Table | Under each theme: KPI name, direction, target, actual, gap %, status |
| Objectives Table | Under each theme: linked OKR objectives, unit, owner, KR count, progress, health, status |
Note: Theme-linked objectives are filtered to ROOT unit and first-level child departments only. Lower-level units are excluded.
Off-track themes are expanded by default; on-track themes are collapsed (Collapse component).
API
GET /dashboard/strategy-compass
Headers: Authorization: Bearer <token>
RBAC: SUPER_ADMIN, ADMIN, STRATEGY_MANAGER
Response fields:
| Field | Description |
|---|---|
activeCycle | Active strategic cycle info |
overallHealth | Weighted overall health score |
summary | KPI status summary counts |
themes[] | Per-theme KPI and objective details |
unitHealthSummary[] | Unit-level objective health (unitId, unitName, unitType, objectiveCount, avgHealth) |
Data Flow
StrategicCycle (ACTIVE)
├─ StrategicTheme (weighted)
│ ├─ StrategicThemeKpi (isActive=true)
│ │ ├─ Own measurements (latest periodEnd)
│ │ └─ or AsIsKpi.measurements (if linked)
│ └─ OkrObjective (linked, from active OKR cycles, ROOT+1st-level units)
│ └─ KeyResults (progress × weight)
├─ OkrCycle (PLANNING | IN_APPROVAL | ACTIVE | REVIEW)
└─ OrgUnit (isRoot=true → children[parentId=rootId, isActive=true])
3. Personal Dashboard
Who: MEMBER
Access: /dashboard
Displays:
- Assigned OKR: My assigned work
- My Progress: Completion %
- Team Activity: What team is doing
Filtering & Navigation
Date Range Filter
Select: Last 30 days / Quarter / Year
Shows: Only data in that period
Uses: WBR/MBR/QBR reporting
Theme Filter
Select theme → Shows only related:
- OKRs
- KPIs
- Owners
- Resource allocation
Owner Filter
Select owner → Shows their:
- Assigned OKRs
- Teams
- KPI performance
Status Filter
Green: On track (0.7-1.0)
Yellow: At risk (0.4-0.6)
Red: Failed (0.0-0.3)
Export & Sharing
Export to Excel
- Export button on Dashboard
- Select: Metric type (OKR, KPI, Alignment)
- Select: Date range
- Download → Excel file
Share Dashboard
- Share button → Copy link
- Recipients can view (read-only)
- Auto-updates with latest data
Schedule Reports
- Settings → Scheduled Reports
- Frequency: Weekly / Monthly / Quarterly
- Recipients: Email list
- Content: Which metrics to include
- Schedule
Tips
✅ Best practices:
- Check dashboard before WBR/MBR/QBR
- Use filters to focus on key areas
- Track trend, not just current value
- Align OKR scores with unit dashboards
❌ Common mistakes:
- Ignoring yellow alerts (early intervention)
- Assuming green = all's well (check underlying KPIs)
- Not updating KPIs regularly (stale data)
Troubleshooting
Dashboard data not updating? → KPIs might need manual input. Check with Admin.
I cannot see metrics? → Permission check. STRATEGY_MANAGER role required.
Export broken? → Report support, data integrity check.