KPI Performance System Implementation
Overview
The KPI system is a coaching-oriented staff performance framework built on a core philosophy: KPIs belong to the person, not the contract. Contracts trigger KPI attachment, but performance history persists across the entire employment lifecycle — from first hire to final exit. The system is designed around growth language ("exceeding", "meeting", "growing") rather than deficit language ("below", "failing"), and recognises that effort counts alongside measurable outcomes.
Design Principles
| Principle | Implementation |
|---|---|
| Person-centric | KPIs attach to staff_id, not contract_id. Contract triggers assignment but history is never deleted. |
| Effort matters | Each KPI carries an effort_weight (15–30%) that factors into final scoring. |
| Growth language | Status labels use "exceeding / meeting / growing" — never "below" or "failing". |
| Living Journal | Every score change is recorded with context. Append-only kpi_journal_entries table. |
| Transparency of process | Staff see the evaluation process and their journal entries (where is_visible_to_staff = true), but raw scoring mechanics remain manager-facing. |
Database Schema
All KPI tables reside in the hr schema.
hr.kpi_modules
The KPI template library — the master catalogue of all measurable performance indicators.
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key |
name | text | Display name |
slug | text | URL-safe identifier |
category | kpi_category | One of 9 categories (see enums) |
role_group | kpi_role_group | Target role group (see enums) |
objective | text | What this KPI measures |
measurement_method | text | How performance is assessed |
data_sources | text[] | Array of data source references |
automation_status | text | Level of automated scoring support |
score_type | text | Scoring methodology |
target_score | numeric | Expected performance level |
minimum_score | numeric | Threshold for "growing" status |
effort_weight | numeric | Weight given to effort (0.15–0.30) |
evaluation_frequency | kpi_frequency | How often this KPI is evaluated |
coaching_tips | text[] | Array of coaching suggestions for managers |
is_default_for_role | boolean | Auto-attach when role group matches |
is_seed | boolean | System-provided seed data |
display_order | integer | Sort position in UI |
hr.template_kpis
Links KPI modules to contract templates so KPIs are automatically assigned when a contract is generated.
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key |
template_id | uuid | FK → contract template |
kpi_module_id | uuid | FK → hr.kpi_modules |
weight | numeric | Relative weight within this template |
is_required | boolean | Cannot be removed by managers |
custom_target | numeric | Override target for this template context |
hr.staff_kpis
Individual KPI assignments — the live, per-person performance records.
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key |
staff_id | uuid | FK → staff member |
contract_id | uuid | FK → triggering contract |
kpi_module_id | uuid | FK → hr.kpi_modules |
status | text | Active status of this assignment |
source | text | 'template' or 'manual' |
current_score | numeric | Latest evaluated score |
current_effort_score | numeric | Latest effort component |
previous_score | numeric | Score from prior evaluation |
score_trend | text | Direction of movement |
trend_percentage | numeric | Magnitude of change |
last_evaluated_at | timestamptz | When last scored |
next_evaluation_due | timestamptz | When next evaluation is due |
hr.kpi_journal_entries
The Living Journal — an append-only audit trail of every score change, observation, and coaching note.
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key |
staff_kpi_id | uuid | FK → hr.staff_kpis |
entry_type | journal_entry_type | One of 16 entry types (see enums) |
title | text | Entry heading |
content | text | Full narrative content |
score_impact | numeric | Numerical effect on score |
score_before | numeric | Score prior to this entry |
score_after | numeric | Score after this entry |
effort_recognized | boolean | Whether effort was acknowledged |
effort_notes | text | Narrative on effort observed |
is_visible_to_staff | boolean | Controls staff visibility |
is_pending_approval | boolean | Requires manager sign-off |
linked_catchup_id | uuid | FK → catch-up session (optional) |
linked_incident_id | uuid | FK → incident record (optional) |
created_by | uuid | FK → user who created the entry |
Enums
kpi_category (9 values)
culture, productivity, communication, safety,
care_quality, financial, leadership, compliance, operational
kpi_role_group (15 values)
There are 15 distinct role groups, each with approximately 5 default KPIs. Examples include support workers, team leaders, registered nurses, administration, management, and allied health professionals.
journal_entry_type (16 values)
Covers the full range of journal interactions including observations, coaching sessions, incident links, catch-up notes, score adjustments, effort recognitions, and approval workflows.
kpi_frequency
weekly, fortnightly, monthly, quarterly, annually
Universal KPIs
Five KPIs apply to all staff regardless of role group:
| KPI | Category | Applies To |
|---|---|---|
| Code of Conduct & Culture | culture | All staff |
| Attendance & Reliability | operational | All staff |
| WHS & Safety Compliance | safety | All staff |
| Communication Responsiveness | communication | All staff |
| Documentation Quality | compliance | All staff |
These are seeded with is_default_for_role = true across all 15 role groups.
API Endpoints
All endpoints are mounted at /api/v1/.
KPI Module Library
| Method | Path | Description |
|---|---|---|
GET | /hr/kpi-modules | List all KPI modules. Optional ?role_group= filter. |
GET | /hr/kpi-modules/:id | Get a single KPI module by ID. |
Template KPIs
| Method | Path | Description |
|---|---|---|
GET | /hr/templates/:templateId/kpis | List KPIs attached to a contract template. |
PUT | /hr/templates/:templateId/kpis | Update the full set of KPIs for a template. |
Staff KPIs
| Method | Path | Description |
|---|---|---|
GET | /hr/staff/:staffId/kpis | List KPIs for a staff member. Optional ?status=all to include inactive. |
POST | /hr/staff/:staffId/kpis | Manually assign a new KPI to a staff member. |
PATCH | /hr/staff/:staffId/kpis/:kpiId/status | Update the status of a staff KPI assignment. |
POST | /hr/staff/:staffId/deactivate-kpis | Deactivate all active KPIs for a staff member. |
Frontend Integration
Pages
| Page | File | Purpose |
|---|---|---|
| KPI Gallery | page_hr_kpis.html / page_hr_kpis.js | Browse and manage the KPI module library |
| Contracting Wizard | page_hr_contracting.html / page_hr_contracting.js | KPI step in the contract creation wizard |
| Staff Detail | page_staff_detail.html / page_staff_detail.js | Individual staff KPI tab with journal view |
Contract Integration Flow
When a contract is created from a template:
- Template KPIs (
hr.template_kpis) are read for the selected template. - Each template KPI is copied to
hr.staff_kpiswithsource = 'template'. - Managers can add additional KPIs manually (
source = 'manual'). - The KPI step in the contracting wizard displays both required and optional KPIs.
Employment Lifecycle
KPIs follow the staff member through the full employment lifecycle:
Setup → Hiring → Working → Review → Renewal → Role Change → Exit
| Lifecycle Event | KPI Behaviour |
|---|---|
| Contract created | Template KPIs auto-assigned to staff_kpis |
| Working phase | KPIs are actively evaluated per their frequency |
| Review cycle | Journal entries capture coaching and score updates |
| Contract renewal | Existing KPIs persist; new template KPIs may be added |
| Role change | New role-group KPIs assigned; old ones deactivated (not deleted) |
| Contract end / Exit | All active KPIs deactivated; journal history preserved permanently |
KPIs are never deleted — only deactivated. This ensures a complete, auditable performance history for every staff member.
SQL Migrations
| Migration File | Purpose |
|---|---|
20260113_kpi_comprehensive_system.sql | Core schema: all tables, enums, indexes, and seed data |
20260113_kpi_seed_update.sql | Updated seed KPI modules for all 15 role groups |
20260114_kpi_active_status.sql | Added active/inactive status management |
Summary
The KPI system transforms performance management from a punitive checkbox exercise into a coaching-oriented, journal-driven growth framework. By anchoring KPIs to people rather than contracts, recognising effort alongside outcomes, and maintaining a permanent living journal, the system supports transparent and compassionate staff development across every phase of employment.