/hr/performance/appraisals (the list) and /hr/performance/appraisals/:id (one appraisal in detail)
Hitaji 360 is multi-business. An appraisal belongs to the business it was created under, and the list only ever shows appraisals for the business currently selected in the switcher. You cannot read or act on another business’s appraisal — the system answers with a “not found” rather than leaking it. Confirm the right business is selected before you create or change anything.
📷 Screenshot: the Appraisals list with the cycle / status / department filters — to be added.
The appraisals list
The list shows every appraisal in the current business, one row per employee-and-cycle. Each row carries the employee, their department, the cycle, the three component scores (Goal, Self, Feedback), the Final Score, and a status badge. You can filter the list by:- Cycle — narrow to a single appraisal cycle.
- Status — Draft, Pending Review, Submitted or Cancelled.
- Department — free-text match (e.g.
Engineering).
The four scores
Every appraisal carries four numbers, all on a 0–5 scale, shown in the score strip at the top of the detail page and broken down per row inside the tabs.How the Goal Score is built
The Goal Score follows the evaluation method set on the cycle:- Automated (goal progress) — for each KRA the system averages the progress of the employee’s linked goals in that cycle, weights it, and rolls it up. You don’t score KRAs by hand; the Goals / KRAs tab is read-only and shows completion percentage and the resulting goal score per KRA.
- Manual rating — a reviewer scores each KRA row directly from 0 to 5 using the star control in the Goals / KRAs tab. The system weights each score and sums them. Manual scores can only be entered on appraisals whose cycle uses this method; trying to set them on an automated appraisal is rejected.
How the Final Score is built
By default the final score is the plain average of Goal, Self and Feedback. A cycle can instead enable a custom final-score formula (referencinggoal_score, average_feedback_score and self_appraisal_score); when it does, that formula drives the final score instead. Either way the result is always clamped to a valid 0–5.
Weightages must sum to 100%. Self-ratings and (in manual mode) KRA scores are weighted, and the maths assumes the weights on each side add up to 100. If a template edit or a dropped row leaves them out of balance, a score recompute fails loudly rather than quietly under- or over-counting. Fix the weightages on the template (see Related) and recompute.
📷 Screenshot: the score strip (Goal · Self · Avg Feedback · Final) on the appraisal detail page — to be added.
The detail page tabs
What you can edit, and when
An appraisal is only editable while it is in Draft. Once it moves to Pending Review it locks (return it to Draft to edit again), and once Submitted or Cancelled it locks permanently. Manager Remarks are the one exception — they stay editable in both Draft and Pending Review.
Saving self-ratings or manual scores triggers a score refresh automatically, so the score strip updates straight away.
The appraisal workflow (statuses)
An appraisal moves through these states. The action you can take depends on where it is and which permission you hold.
The transitions:
- Submit for Review — Draft → Pending Review. Requires
hr-performance:write. - Approve — Pending Review → Submitted. Requires
hr-performance:approve. This is the finalising step: it does a final score recompute, flips the appraisal to Submitted, and sends a best-effort notification to the employee. (Two people approving at once is safe — only the request that actually flips the state proceeds, so the appraisal is never finalised or notified twice.) - Return to Draft — Pending Review → Draft. Requires
hr-performance:approve. Use this to reopen an appraisal for more editing. - Cancel — Draft or Pending Review → Cancelled. Requires
hr-performance:approve.
Behind the scenes: alongside the status, the system keeps an internal document state (0 = draft, 1 = submitted, 2 = cancelled) following the standard HR “submittable document” convention. You’ll never set it directly — the workflow above drives it — but it is what locks a finalised or cancelled appraisal against further edits.
Cancelling vs deleting a Submitted appraisal
A Submitted appraisal is protected because it can carry issued reward pay. Appraisal rewards (a bonus or an increment) can only be proposed off a Submitted appraisal, and once a reward is approved it materialises real downstream pay — anAdditionalSalary (one-off bonus) or an EmployeePromotion (a salary bump). Cancelling or blindly deleting the parent afterwards would orphan that pay with no audit trail.
So the rules are:
- Cancel is never available on a Submitted appraisal. If you try, you’ll be told: “A submitted appraisal cannot be cancelled — it may carry issued reward pay (bonus / increment). Reverse any rewards through payroll first.” Cancel stays available only for Draft and Pending Review appraisals, which can’t carry issued rewards.
-
Delete of a Submitted appraisal is allowed only when it carries no issued reward. This is the escape hatch. Previously a Submitted appraisal could never be deleted, which in turn blocked its parent cycle from ever being deleted (“Cannot delete a cycle that has appraisals”) — a permanent dead-end for cycles created in error. So the system now lets you purge a Submitted appraisal that never issued any pay, while keeping the hard block where pay was actually issued.
A reward counts as issued when it has been approved or applied, or when it has already stamped a downstream
AdditionalSalary/EmployeePromotion. Reward proposals that were only proposed or were rejected never touch pay, so they don’t block deletion. If an issued reward exists, the delete is refused with: “A submitted appraisal that has issued reward pay (bonus / increment) cannot be deleted. Reverse the reward through payroll first.”
hr-performance:write.
⚠️ Current state: Deleting an appraisal is an API action (DELETE /api/hr/performance/appraisals/:id). The detail page does not yet surface a delete button — it offers Cancel for Draft / Pending Review appraisals, but no delete control for the Submitted-with-no-reward case. Until that button is added, deleting such an appraisal (for example to unblock a cycle delete) has to be done by an administrator through the API. (Flagged for the team.)
Permissions
All endpoints are tenant- and business-scoped. A request for an appraisal that belongs to a different business fails closed with a “not found” — it never reveals that the appraisal exists.
Related
- Performance overview — how the performance module fits together
- Appraisal cycles — launching a cycle, which generates the appraisals; and deleting a cycle
- Appraisal templates — the KRAs, criteria and weightages an appraisal is built from
- Goals — the goals whose progress feeds the automated Goal Score
- 360° feedback — submitting feedback that feeds the Avg Feedback score
- Appraisal rewards — proposing and approving bonuses / increments off a submitted appraisal