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