rename(phase 1): CapaKraken → Nexus across code, UI, docs, CI (#61)
CI / Architecture Guardrails (push) Successful in 2m38s
CI / Assistant Split Regression (push) Successful in 3m33s
CI / Typecheck (push) Successful in 3m51s
CI / Lint (push) Successful in 5m2s
CI / E2E Tests (push) Has been cancelled
CI / Fresh-Linux Docker Deploy (push) Has been cancelled
CI / Release Images (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled

rename(phase 1): CapaKraken → Nexus across code, UI, docs, CI (#61)

Co-authored-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
Co-committed-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
This commit was merged in pull request #61.
This commit is contained in:
2026-05-21 16:28:40 +02:00
committed by Hartmut
parent d9a7ec0338
commit b41c1d2501
943 changed files with 24548 additions and 16832 deletions
@@ -1,6 +1,13 @@
import type { WeekdayAvailability } from "@capakraken/shared";
import type { WeekdayAvailability } from "@nexus/shared";
import { fmtEur } from "../lib/format-utils.js";
import { type GraphLink, type GraphNode, fmtPct, fmtNum, l, n } from "./computation-graph-shared.js";
import {
type GraphLink,
type GraphNode,
fmtPct,
fmtNum,
l,
n,
} from "./computation-graph-shared.js";
type ResourceGraphResolvedHoliday = {
date: string;
@@ -116,84 +123,510 @@ function describeWeeklyAvailability(availability: WeekdayAvailability): {
}
export function buildResourceGraphSnapshot(input: ResourceGraphPresentationInput) {
const { totalHours: weeklyTotalHours, label: availabilityLabel } = describeWeeklyAvailability(input.weeklyAvailability);
const { totalHours: weeklyTotalHours, label: availabilityLabel } = describeWeeklyAvailability(
input.weeklyAvailability,
);
const hasScheduleRules = !!input.scheduleRules;
const nodes: GraphNode[] = [
n("input.fte", "FTE", fmtNum(input.resource.fte, 2), "ratio", "INPUT", "Resource FTE factor", 0),
n("input.country", "Country", input.resource.country?.name ?? input.resource.country?.code ?? "—", "text", "INPUT", "Country used for base working-time and national holiday rules", 0),
n("input.state", "State", input.resource.federalState ?? "—", "text", "INPUT", "Federal state / region used for regional holidays", 0),
n("input.city", "City", input.resource.metroCity?.name ?? "—", "text", "INPUT", "City / metro used for local holidays", 0),
n("input.holidayContext", "Holiday Context", input.holidayScopeSummary, "text", "INPUT", "Resolved holiday scope chain: country / state / city", 0),
n("input.holidayExamples", "Holiday Dates", input.holidayExamples, "text", "INPUT", `Resolved holidays in ${input.month}; scopes: COUNTRY ${input.holidayScopeBreakdown.COUNTRY ?? 0}, STATE ${input.holidayScopeBreakdown.STATE ?? 0}, CITY ${input.holidayScopeBreakdown.CITY ?? 0}`, 0),
n("input.dailyHours", "Country Hours", `${input.dailyHours} h`, "hours", "INPUT", `Base daily working hours (${input.resource.country?.code ?? "?"})`, 0),
n(
"input.fte",
"FTE",
fmtNum(input.resource.fte, 2),
"ratio",
"INPUT",
"Resource FTE factor",
0,
),
n(
"input.country",
"Country",
input.resource.country?.name ?? input.resource.country?.code ?? "—",
"text",
"INPUT",
"Country used for base working-time and national holiday rules",
0,
),
n(
"input.state",
"State",
input.resource.federalState ?? "—",
"text",
"INPUT",
"Federal state / region used for regional holidays",
0,
),
n(
"input.city",
"City",
input.resource.metroCity?.name ?? "—",
"text",
"INPUT",
"City / metro used for local holidays",
0,
),
n(
"input.holidayContext",
"Holiday Context",
input.holidayScopeSummary,
"text",
"INPUT",
"Resolved holiday scope chain: country / state / city",
0,
),
n(
"input.holidayExamples",
"Holiday Dates",
input.holidayExamples,
"text",
"INPUT",
`Resolved holidays in ${input.month}; scopes: COUNTRY ${input.holidayScopeBreakdown.COUNTRY ?? 0}, STATE ${input.holidayScopeBreakdown.STATE ?? 0}, CITY ${input.holidayScopeBreakdown.CITY ?? 0}`,
0,
),
n(
"input.dailyHours",
"Country Hours",
`${input.dailyHours} h`,
"hours",
"INPUT",
`Base daily working hours (${input.resource.country?.code ?? "?"})`,
0,
),
...(hasScheduleRules
? [n("input.scheduleRules", "Schedule Rules", "Spain", "—", "INPUT", "Variable daily hours (regular/friday/summer)", 0)]
? [
n(
"input.scheduleRules",
"Schedule Rules",
"Spain",
"—",
"INPUT",
"Variable daily hours (regular/friday/summer)",
0,
),
]
: []),
n("input.weeklyAvail", "Weekly Avail.", `${weeklyTotalHours}h`, "h/week", "INPUT", `Resource availability: ${availabilityLabel}`, 0),
n("input.lcrCents", "LCR", fmtEur(input.resource.lcrCents), "cents/h", "INPUT", "Loaded Cost Rate per hour", 0),
n("input.hoursPerDay", "Hours/Day", fmtNum(input.avgHoursPerDay), "hours", "INPUT", "Average hours/day across assignments", 0),
n("input.absences", "Absences", `${input.absenceCount}`, "count", "INPUT", `Absence days in ${input.month} (${input.vacationDayCount} vacation, ${input.sickDayCount} sick${input.halfDayCount > 0 ? `, ${input.halfDayCount} half-day` : ""})`, 0),
n("input.publicHolidays", "Public Holidays", `${input.publicHolidayCount}`, "count", "INPUT", `Resolved holidays in ${input.month}; ${input.publicHolidayWorkdayCount} hit configured working days`, 0),
n("input.calcRules", "Active Rules", `${input.calcRulesCount}`, "count", "INPUT", "Active calculation rules", 0),
n("input.targetPct", "Target", fmtPct(input.targetPct), "%", "INPUT", `Chargeability target (${input.resource.managementLevelGroup?.name ?? "legacy"})`, 0),
n("input.assignmentCount", "Assignments", `${input.assignmentCount}`, "count", "INPUT", `Active assignments in ${input.month}`, 0),
n(
"input.weeklyAvail",
"Weekly Avail.",
`${weeklyTotalHours}h`,
"h/week",
"INPUT",
`Resource availability: ${availabilityLabel}`,
0,
),
n(
"input.lcrCents",
"LCR",
fmtEur(input.resource.lcrCents),
"cents/h",
"INPUT",
"Loaded Cost Rate per hour",
0,
),
n(
"input.hoursPerDay",
"Hours/Day",
fmtNum(input.avgHoursPerDay),
"hours",
"INPUT",
"Average hours/day across assignments",
0,
),
n(
"input.absences",
"Absences",
`${input.absenceCount}`,
"count",
"INPUT",
`Absence days in ${input.month} (${input.vacationDayCount} vacation, ${input.sickDayCount} sick${input.halfDayCount > 0 ? `, ${input.halfDayCount} half-day` : ""})`,
0,
),
n(
"input.publicHolidays",
"Public Holidays",
`${input.publicHolidayCount}`,
"count",
"INPUT",
`Resolved holidays in ${input.month}; ${input.publicHolidayWorkdayCount} hit configured working days`,
0,
),
n(
"input.calcRules",
"Active Rules",
`${input.calcRulesCount}`,
"count",
"INPUT",
"Active calculation rules",
0,
),
n(
"input.targetPct",
"Target",
fmtPct(input.targetPct),
"%",
"INPUT",
`Chargeability target (${input.resource.managementLevelGroup?.name ?? "legacy"})`,
0,
),
n(
"input.assignmentCount",
"Assignments",
`${input.assignmentCount}`,
"count",
"INPUT",
`Active assignments in ${input.month}`,
0,
),
n("sah.calendarDays", "Calendar Days", `${input.sahCalendarDays}`, "days", "SAH", "Total calendar days in period", 1),
n("sah.weekendDays", "Weekend Days", `${input.sahWeekendDays}`, "days", "SAH", "Saturday + Sunday count", 1),
n("sah.grossWorkingDays", "Gross Work Days", `${input.baseWorkingDays}`, "days", "SAH", "Working days from the resource-specific weekly availability before holidays/absences", 1, "count(availability > 0)"),
n("sah.baseHours", "Base Hours", fmtNum(input.baseAvailableHours), "hours", "SAH", "Available hours from weekly availability before holiday/absence deductions", 1, "Σ(daily availability)"),
n("sah.publicHolidayDays", "Holiday Ded.", `${input.publicHolidayWorkdayCount}`, "days", "SAH", "Holiday workdays deducted after applying country/state/city scope and weekday availability", 1),
n("sah.publicHolidayHours", "Holiday Hrs Ded.", fmtNum(input.publicHolidayHoursDeduction), "hours", "SAH", "Hours removed by resolved public holidays", 1, "Σ(availability on holiday dates)"),
n("sah.absenceDays", "Absence Ded.", `${input.absenceCount}`, "days", "SAH", "Vacation/sick days that hit working days and are not already public holidays", 1),
n("sah.absenceHours", "Absence Hrs Ded.", fmtNum(input.absenceHoursDeduction), "hours", "SAH", "Hours removed by vacation/sick absences", 1, "Σ(availability × absence fraction)"),
n("sah.netWorkingDays", "Net Work Days", `${input.effectiveWorkingDays}`, "days", "SAH", "Remaining working days after holiday and absence deductions", 2, "gross - holidays - absences"),
n("sah.effectiveHoursPerDay", "Eff. Hrs/Day", fmtNum(input.effectiveHoursPerWorkingDay), "hours", "SAH", "Average effective hours per remaining working day", 2, "SAH / net work days"),
n("sah.sah", "SAH", fmtNum(input.effectiveAvailableHours), "hours", "SAH", "Effective available hours after weekly availability, local holidays and absences", 2, "base hours - holiday hours - absence hours"),
n(
"sah.calendarDays",
"Calendar Days",
`${input.sahCalendarDays}`,
"days",
"SAH",
"Total calendar days in period",
1,
),
n(
"sah.weekendDays",
"Weekend Days",
`${input.sahWeekendDays}`,
"days",
"SAH",
"Saturday + Sunday count",
1,
),
n(
"sah.grossWorkingDays",
"Gross Work Days",
`${input.baseWorkingDays}`,
"days",
"SAH",
"Working days from the resource-specific weekly availability before holidays/absences",
1,
"count(availability > 0)",
),
n(
"sah.baseHours",
"Base Hours",
fmtNum(input.baseAvailableHours),
"hours",
"SAH",
"Available hours from weekly availability before holiday/absence deductions",
1,
"Σ(daily availability)",
),
n(
"sah.publicHolidayDays",
"Holiday Ded.",
`${input.publicHolidayWorkdayCount}`,
"days",
"SAH",
"Holiday workdays deducted after applying country/state/city scope and weekday availability",
1,
),
n(
"sah.publicHolidayHours",
"Holiday Hrs Ded.",
fmtNum(input.publicHolidayHoursDeduction),
"hours",
"SAH",
"Hours removed by resolved public holidays",
1,
"Σ(availability on holiday dates)",
),
n(
"sah.absenceDays",
"Absence Ded.",
`${input.absenceCount}`,
"days",
"SAH",
"Vacation/sick days that hit working days and are not already public holidays",
1,
),
n(
"sah.absenceHours",
"Absence Hrs Ded.",
fmtNum(input.absenceHoursDeduction),
"hours",
"SAH",
"Hours removed by vacation/sick absences",
1,
"Σ(availability × absence fraction)",
),
n(
"sah.netWorkingDays",
"Net Work Days",
`${input.effectiveWorkingDays}`,
"days",
"SAH",
"Remaining working days after holiday and absence deductions",
2,
"gross - holidays - absences",
),
n(
"sah.effectiveHoursPerDay",
"Eff. Hrs/Day",
fmtNum(input.effectiveHoursPerWorkingDay),
"hours",
"SAH",
"Average effective hours per remaining working day",
2,
"SAH / net work days",
),
n(
"sah.sah",
"SAH",
fmtNum(input.effectiveAvailableHours),
"hours",
"SAH",
"Effective available hours after weekly availability, local holidays and absences",
2,
"base hours - holiday hours - absence hours",
),
n("alloc.workingDays", "Work Days", `${input.totalWorkingDaysInMonth}`, "days", "ALLOCATION", "Working days covered by assignments in period", 1, "Σ(overlap workdays)"),
n("alloc.totalHours", "Total Hours", fmtNum(input.totalAllocHours), "hours", "ALLOCATION", "Sum of effective hours across assignments", 2, "Σ(min(h/day, avail) × workdays)"),
n("alloc.dailyCostCents", "Daily Cost", fmtEur(input.dailyCostCents), "EUR", "ALLOCATION", "Cost per working day", 1, "hoursPerDay × LCR"),
n("alloc.totalCostCents", "Total Cost", fmtEur(input.totalAllocCostCents), "EUR", "ALLOCATION", "Sum of daily costs", 2, "Σ(dailyCost × workdays)"),
n("alloc.utilizationPct", "Utilization", `${input.utilizationPct.toFixed(1)}%`, "%", "ALLOCATION", "Allocation utilization: allocated hours / SAH", 3, "totalHours / SAH × 100"),
n(
"alloc.workingDays",
"Work Days",
`${input.totalWorkingDaysInMonth}`,
"days",
"ALLOCATION",
"Working days covered by assignments in period",
1,
"Σ(overlap workdays)",
),
n(
"alloc.totalHours",
"Total Hours",
fmtNum(input.totalAllocHours),
"hours",
"ALLOCATION",
"Sum of effective hours across assignments",
2,
"Σ(min(h/day, avail) × workdays)",
),
n(
"alloc.dailyCostCents",
"Daily Cost",
fmtEur(input.dailyCostCents),
"EUR",
"ALLOCATION",
"Cost per working day",
1,
"hoursPerDay × LCR",
),
n(
"alloc.totalCostCents",
"Total Cost",
fmtEur(input.totalAllocCostCents),
"EUR",
"ALLOCATION",
"Sum of daily costs",
2,
"Σ(dailyCost × workdays)",
),
n(
"alloc.utilizationPct",
"Utilization",
`${input.utilizationPct.toFixed(1)}%`,
"%",
"ALLOCATION",
"Allocation utilization: allocated hours / SAH",
3,
"totalHours / SAH × 100",
),
...(input.hasRulesEffect
? [
n("alloc.chargeableHours", "Chargeable Hrs", fmtNum(input.totalChargeableHours), "hours", "ALLOCATION", "Rules-adjusted chargeable hours", 2, "rules-adjusted"),
n("alloc.projectCostCents", "Project Cost", fmtEur(input.totalProjectCostCents), "EUR", "ALLOCATION", "Rules-adjusted project cost", 2, "rules-adjusted"),
]
n(
"alloc.chargeableHours",
"Chargeable Hrs",
fmtNum(input.totalChargeableHours),
"hours",
"ALLOCATION",
"Rules-adjusted chargeable hours",
2,
"rules-adjusted",
),
n(
"alloc.projectCostCents",
"Project Cost",
fmtEur(input.totalProjectCostCents),
"EUR",
"ALLOCATION",
"Rules-adjusted project cost",
2,
"rules-adjusted",
),
]
: []),
...(input.absenceCount > 0
? [
n("rules.activeRules", "Matched Rules", `${input.calcRulesCount} rules`, "—", "RULES", "Rules evaluated for absence days", 1),
n("rules.costEffect", "Cost Effect", input.hasRulesEffect ? "ZERO" : "—", "—", "RULES", "How absent days affect project cost", 1, "CHARGE / ZERO / REDUCE"),
n("rules.chgEffect", "Chg Effect", input.hasRulesEffect ? "COUNT" : "—", "—", "RULES", "How absent days affect chargeability", 1, "COUNT / SKIP"),
...(input.hasRulesEffect
? [n("rules.costReduction", "Cost Reduction", "per rule", "—", "RULES", "Cost reduction percentage applied to absent hours", 2, "normalCost × (100 - reductionPct) / 100")]
: []),
]
n(
"rules.activeRules",
"Matched Rules",
`${input.calcRulesCount} rules`,
"—",
"RULES",
"Rules evaluated for absence days",
1,
),
n(
"rules.costEffect",
"Cost Effect",
input.hasRulesEffect ? "ZERO" : "—",
"—",
"RULES",
"How absent days affect project cost",
1,
"CHARGE / ZERO / REDUCE",
),
n(
"rules.chgEffect",
"Chg Effect",
input.hasRulesEffect ? "COUNT" : "—",
"—",
"RULES",
"How absent days affect chargeability",
1,
"COUNT / SKIP",
),
...(input.hasRulesEffect
? [
n(
"rules.costReduction",
"Cost Reduction",
"per rule",
"—",
"RULES",
"Cost reduction percentage applied to absent hours",
2,
"normalCost × (100 - reductionPct) / 100",
),
]
: []),
]
: []),
n("chg.chgHours", "Chg Hours", fmtNum(input.chargeableHours), "hours", "CHARGEABILITY", "Total chargeable hours against effective SAH", 2, "chargeability × SAH"),
n("chg.chg", "Chargeability", fmtPct(input.forecast.chg), "%", "CHARGEABILITY", "Chargeability ratio", 3, "chgHours / SAH"),
n(
"chg.chgHours",
"Chg Hours",
fmtNum(input.chargeableHours),
"hours",
"CHARGEABILITY",
"Total chargeable hours against effective SAH",
2,
"chargeability × SAH",
),
n(
"chg.chg",
"Chargeability",
fmtPct(input.forecast.chg),
"%",
"CHARGEABILITY",
"Chargeability ratio",
3,
"chgHours / SAH",
),
...(input.forecast.bd > 0
? [n("chg.bd", "BD Ratio", fmtPct(input.forecast.bd), "%", "CHARGEABILITY", `Business development: ${fmtNum(input.forecast.bd * input.effectiveAvailableHours)}h`, 3, "bdHours / SAH")]
? [
n(
"chg.bd",
"BD Ratio",
fmtPct(input.forecast.bd),
"%",
"CHARGEABILITY",
`Business development: ${fmtNum(input.forecast.bd * input.effectiveAvailableHours)}h`,
3,
"bdHours / SAH",
),
]
: []),
...(input.forecast.mdi > 0
? [n("chg.mdi", "MD&I Ratio", fmtPct(input.forecast.mdi), "%", "CHARGEABILITY", `MD&I hours: ${fmtNum(input.forecast.mdi * input.effectiveAvailableHours)}h`, 3, "mdiHours / SAH")]
? [
n(
"chg.mdi",
"MD&I Ratio",
fmtPct(input.forecast.mdi),
"%",
"CHARGEABILITY",
`MD&I hours: ${fmtNum(input.forecast.mdi * input.effectiveAvailableHours)}h`,
3,
"mdiHours / SAH",
),
]
: []),
...(input.forecast.mo > 0
? [n("chg.mo", "M&O Ratio", fmtPct(input.forecast.mo), "%", "CHARGEABILITY", `M&O hours: ${fmtNum(input.forecast.mo * input.effectiveAvailableHours)}h`, 3, "moHours / SAH")]
? [
n(
"chg.mo",
"M&O Ratio",
fmtPct(input.forecast.mo),
"%",
"CHARGEABILITY",
`M&O hours: ${fmtNum(input.forecast.mo * input.effectiveAvailableHours)}h`,
3,
"moHours / SAH",
),
]
: []),
...(input.forecast.pdr > 0
? [n("chg.pdr", "PD&R Ratio", fmtPct(input.forecast.pdr), "%", "CHARGEABILITY", `PD&R hours: ${fmtNum(input.forecast.pdr * input.effectiveAvailableHours)}h`, 3, "pdrHours / SAH")]
? [
n(
"chg.pdr",
"PD&R Ratio",
fmtPct(input.forecast.pdr),
"%",
"CHARGEABILITY",
`PD&R hours: ${fmtNum(input.forecast.pdr * input.effectiveAvailableHours)}h`,
3,
"pdrHours / SAH",
),
]
: []),
...(input.forecast.absence > 0
? [n("chg.absence", "Absence Ratio", fmtPct(input.forecast.absence), "%", "CHARGEABILITY", `Absence hours: ${fmtNum(input.forecast.absence * input.effectiveAvailableHours)}h`, 3, "absenceHours / SAH")]
? [
n(
"chg.absence",
"Absence Ratio",
fmtPct(input.forecast.absence),
"%",
"CHARGEABILITY",
`Absence hours: ${fmtNum(input.forecast.absence * input.effectiveAvailableHours)}h`,
3,
"absenceHours / SAH",
),
]
: []),
n("chg.unassigned", "Unassigned", fmtPct(input.forecast.unassigned), "%", "CHARGEABILITY", `${fmtNum(input.forecast.unassigned * input.effectiveAvailableHours)}h of ${fmtNum(input.effectiveAvailableHours)}h SAH not assigned`, 3, "max(0, SAH - assigned) / SAH"),
n("chg.target", "Target", fmtPct(input.targetPct), "%", "CHARGEABILITY", "Chargeability target from management level", 3),
n("chg.gap", "Gap to Target", `${input.forecast.chg - input.targetPct >= 0 ? "+" : ""}${((input.forecast.chg - input.targetPct) * 100).toFixed(1)} pp`, "pp", "CHARGEABILITY", `Chargeability (${fmtPct(input.forecast.chg)}) vs. target (${fmtPct(input.targetPct)})`, 3, "chargeability target"),
n(
"chg.unassigned",
"Unassigned",
fmtPct(input.forecast.unassigned),
"%",
"CHARGEABILITY",
`${fmtNum(input.forecast.unassigned * input.effectiveAvailableHours)}h of ${fmtNum(input.effectiveAvailableHours)}h SAH not assigned`,
3,
"max(0, SAH - assigned) / SAH",
),
n(
"chg.target",
"Target",
fmtPct(input.targetPct),
"%",
"CHARGEABILITY",
"Chargeability target from management level",
3,
),
n(
"chg.gap",
"Gap to Target",
`${input.forecast.chg - input.targetPct >= 0 ? "+" : ""}${((input.forecast.chg - input.targetPct) * 100).toFixed(1)} pp`,
"pp",
"CHARGEABILITY",
`Chargeability (${fmtPct(input.forecast.chg)}) vs. target (${fmtPct(input.targetPct)})`,
3,
"chargeability target",
),
...input.budgetNodes,
];
@@ -209,7 +642,9 @@ export function buildResourceGraphSnapshot(input: ResourceGraphPresentationInput
l("input.holidayExamples", "sah.publicHolidayDays", "resolved dates", 2),
l("input.holidayExamples", "sah.publicHolidayHours", "remove matching day hours", 2),
l("input.absences", "sah.absenceHours", "remove absence fractions", 1),
...(hasScheduleRules ? [l("input.scheduleRules", "sah.effectiveHoursPerDay", "variable h/day", 1)] : []),
...(hasScheduleRules
? [l("input.scheduleRules", "sah.effectiveHoursPerDay", "variable h/day", 1)]
: []),
l("sah.calendarDays", "sah.grossWorkingDays", " weekends", 2),
l("sah.weekendDays", "sah.grossWorkingDays", "", 1),
l("input.publicHolidays", "sah.publicHolidayDays", "∩ workdays", 1),
@@ -237,24 +672,31 @@ export function buildResourceGraphSnapshot(input: ResourceGraphPresentationInput
...(input.absenceCount > 0
? [
l("input.calcRules", "rules.activeRules", "filter active", 1),
l("input.absences", "rules.activeRules", "match trigger", 1),
l("rules.activeRules", "rules.costEffect", "→ effect", 1),
l("rules.activeRules", "rules.chgEffect", "→ effect", 1),
]
l("input.calcRules", "rules.activeRules", "filter active", 1),
l("input.absences", "rules.activeRules", "match trigger", 1),
l("rules.activeRules", "rules.costEffect", "→ effect", 1),
l("rules.activeRules", "rules.chgEffect", "→ effect", 1),
]
: []),
...(input.hasRulesEffect
? [
l("rules.costEffect", "alloc.projectCostCents", "apply", 2),
l("alloc.totalCostCents", "alloc.projectCostCents", "adjust", 1),
l("rules.chgEffect", "alloc.chargeableHours", "apply", 2),
l("alloc.totalHours", "alloc.chargeableHours", "adjust", 1),
...(input.absenceCount > 0 ? [l("rules.costEffect", "rules.costReduction", "reduce %", 1)] : []),
]
l("rules.costEffect", "alloc.projectCostCents", "apply", 2),
l("alloc.totalCostCents", "alloc.projectCostCents", "adjust", 1),
l("rules.chgEffect", "alloc.chargeableHours", "apply", 2),
l("alloc.totalHours", "alloc.chargeableHours", "adjust", 1),
...(input.absenceCount > 0
? [l("rules.costEffect", "rules.costReduction", "reduce %", 1)]
: []),
]
: []),
l(input.hasRulesEffect ? "alloc.chargeableHours" : "alloc.totalHours", "chg.chgHours", "Σ Chg", 2),
l(
input.hasRulesEffect ? "alloc.chargeableHours" : "alloc.totalHours",
"chg.chgHours",
"Σ Chg",
2,
),
l("chg.chgHours", "chg.chg", "÷ SAH", 2),
l("sah.sah", "chg.chg", "÷", 2),
...(input.forecast.bd > 0 ? [l("sah.sah", "chg.bd", "÷", 1)] : []),