gistfile1.txt
· 1.9 KiB · Text
Raw
/**
* Derive a Program's priority from the 2-axis strategic-evaluation matrix
* (doc 13 §2.2): strategic_value (1–10) × internal_impact (1–10). A missing/zero
* axis = "not yet rated". High = 7–10, low = 1–6.
*
* ```
* strategic 1–6 strategic 7–10
* internal 7–10 SELECTIVE PRIORITY
* internal 1–6 BUSINESS_AS_USUAL MANAGE_RISK
* ```
*
* ⚠ The two off-diagonal cells were SWAPPED here until 2026-07-27. Source of truth is
* the customer's own deck — `.sample/290713 KAI PMO_Dashboard Progress_v2.pdf` p.9
* ("Matriks Prioritisasi Program DS"), whose 2×2 legend is anchored on the crossing of
* the two threshold lines. Its tier copy settles it independently: Selektif = "perkuat
* NILAI STRATEGIS program sebelum eksekusi penuh" (so strategic is the weak axis) and
* Manage Risk = "tinjau kelayakan dan DAMPAK secara berkala" (impact is the weak axis).
* p.14's appendix agrees — "Konsesi Stasiun Jabodetabek" is SELEKTIF (commercial impact
* high, national-political value low). Do not re-swap to match an older doc table.
*
* This is the SINGLE source of the mapping — the `programs.priority` column is a
* denormalized cache recomputed here on every create/update.
* @param strategicValue - Strategic / political value (1–10) or null
* @param internalImpact - Internal company impact (1–10) or null
* @returns The derived ProgramPriority enum value
*/
export function deriveProgramPriority(
strategicValue: number | null | undefined,
internalImpact: number | null | undefined
): ProgramPriority {
if (!strategicValue || !internalImpact) return 'NOT_RATED';
const highStrategic = strategicValue >= 7;
const highInternal = internalImpact >= 7;
if (highStrategic && highInternal) return 'PRIORITY';
if (highInternal) return 'SELECTIVE'; // low strategic, high internal
if (highStrategic) return 'MANAGE_RISK'; // high strategic, low internal
return 'BUSINESS_AS_USUAL';
}
| 1 | /** |
| 2 | * Derive a Program's priority from the 2-axis strategic-evaluation matrix |
| 3 | * (doc 13 §2.2): strategic_value (1–10) × internal_impact (1–10). A missing/zero |
| 4 | * axis = "not yet rated". High = 7–10, low = 1–6. |
| 5 | * |
| 6 | * ``` |
| 7 | * strategic 1–6 strategic 7–10 |
| 8 | * internal 7–10 SELECTIVE PRIORITY |
| 9 | * internal 1–6 BUSINESS_AS_USUAL MANAGE_RISK |
| 10 | * ``` |
| 11 | * |
| 12 | * ⚠ The two off-diagonal cells were SWAPPED here until 2026-07-27. Source of truth is |
| 13 | * the customer's own deck — `.sample/290713 KAI PMO_Dashboard Progress_v2.pdf` p.9 |
| 14 | * ("Matriks Prioritisasi Program DS"), whose 2×2 legend is anchored on the crossing of |
| 15 | * the two threshold lines. Its tier copy settles it independently: Selektif = "perkuat |
| 16 | * NILAI STRATEGIS program sebelum eksekusi penuh" (so strategic is the weak axis) and |
| 17 | * Manage Risk = "tinjau kelayakan dan DAMPAK secara berkala" (impact is the weak axis). |
| 18 | * p.14's appendix agrees — "Konsesi Stasiun Jabodetabek" is SELEKTIF (commercial impact |
| 19 | * high, national-political value low). Do not re-swap to match an older doc table. |
| 20 | * |
| 21 | * This is the SINGLE source of the mapping — the `programs.priority` column is a |
| 22 | * denormalized cache recomputed here on every create/update. |
| 23 | * @param strategicValue - Strategic / political value (1–10) or null |
| 24 | * @param internalImpact - Internal company impact (1–10) or null |
| 25 | * @returns The derived ProgramPriority enum value |
| 26 | */ |
| 27 | export function deriveProgramPriority( |
| 28 | strategicValue: number | null | undefined, |
| 29 | internalImpact: number | null | undefined |
| 30 | ): ProgramPriority { |
| 31 | if (!strategicValue || !internalImpact) return 'NOT_RATED'; |
| 32 | const highStrategic = strategicValue >= 7; |
| 33 | const highInternal = internalImpact >= 7; |
| 34 | if (highStrategic && highInternal) return 'PRIORITY'; |
| 35 | if (highInternal) return 'SELECTIVE'; // low strategic, high internal |
| 36 | if (highStrategic) return 'MANAGE_RISK'; // high strategic, low internal |
| 37 | return 'BUSINESS_AS_USUAL'; |
| 38 | } |