feat(evaluations): define performance levels
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
2be1081e92
commit
9955c376f9
1 changed files with 51 additions and 0 deletions
51
src/lib/evaluations/levels.ts
Normal file
51
src/lib/evaluations/levels.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* Pure performance level definitions for leadership evaluations.
|
||||
*
|
||||
* This module has no Payload imports — it is safe to use from server actions,
|
||||
* integration tests, and (later) frontend components. The UI renders these as
|
||||
* bar/gradient displays; `score` drives the numeric aggregation and `color`
|
||||
* the per-level accent.
|
||||
*/
|
||||
|
||||
export interface PerformanceLevel {
|
||||
/** Stable identifier stored on evaluation docs. */
|
||||
id: string;
|
||||
/** Human-readable label, e.g. shown as "OPERATOR PERFORMANCE LEVEL: EXCELLENT". */
|
||||
label: string;
|
||||
/** Numeric score (0–100) used for aggregate bar/percentage display. */
|
||||
score: number;
|
||||
/** Hex color for UI bars/gradients. */
|
||||
color: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The performance scale, best to worst. At least five levels are required by the
|
||||
* leadership-evaluations feature; six are defined so the top of the scale has room
|
||||
* above "EXCELLENT" without collapsing distinctions.
|
||||
*/
|
||||
export const PERFORMANCE_LEVELS = [
|
||||
{ id: "exceptional", label: "EXCEPTIONAL", score: 100, color: "#34d399" },
|
||||
{ id: "excellent", label: "EXCELLENT", score: 85, color: "#4ade80" },
|
||||
{ id: "proficient", label: "PROFICIENT", score: 70, color: "#a3e635" },
|
||||
{ id: "adequate", label: "ADEQUATE", score: 55, color: "#fbbf24" },
|
||||
{ id: "moderate", label: "MODERATE", score: 40, color: "#94a3b8" },
|
||||
{ id: "under-review", label: "UNDER REVIEW", score: 25, color: "#f87171" },
|
||||
] as const satisfies readonly PerformanceLevel[];
|
||||
|
||||
export type PerformanceLevelId = (typeof PERFORMANCE_LEVELS)[number]["id"];
|
||||
|
||||
const LEVEL_IDS: ReadonlySet<string> = new Set(PERFORMANCE_LEVELS.map((l) => l.id));
|
||||
|
||||
/** Type guard for runtime-validated level ids (DB/API input). */
|
||||
export function isPerformanceLevelId(value: unknown): value is PerformanceLevelId {
|
||||
return typeof value === "string" && LEVEL_IDS.has(value);
|
||||
}
|
||||
|
||||
/** Resolve a level definition by id, or null when unknown. */
|
||||
export function getPerformanceLevel(id: string): PerformanceLevel | null {
|
||||
return PERFORMANCE_LEVELS.find((l) => l.id === id) ?? null;
|
||||
}
|
||||
|
||||
export function getLeadershipDisplayLabel(level: Pick<PerformanceLevel, "id" | "label">): string {
|
||||
return level.id === "under-review" ? "NEEDS WORK" : level.label;
|
||||
}
|
||||
Loading…
Reference in a new issue