feat(platform): checkpoint current implementation state

This commit is contained in:
2026-04-01 07:42:03 +02:00
parent 3e53471f05
commit 8c5be51251
125 changed files with 10269 additions and 17808 deletions
@@ -0,0 +1,87 @@
import { describe, expect, it } from "vitest";
import {
buildReportWorkbookSheets,
buildResourceMonthExplainabilitySheetRows,
} from "./reportBuilderExplainability.js";
describe("reportBuilderExplainability", () => {
it("builds a readable explainability sheet for resource month reports", () => {
const rows = buildResourceMonthExplainabilitySheetRows(
{
entity: "resource_month",
periodMonth: "2026-01",
locationContextColumns: ["countryCode", "federalState"],
holidayMetricColumns: ["monthlyPublicHolidayCount"],
absenceMetricColumns: ["monthlyAbsenceHoursDeduction"],
capacityMetricColumns: ["monthlyBaseAvailableHours", "monthlySahHours"],
chargeabilityMetricColumns: ["monthlyActualChargeabilityPct"],
missingRecommendedColumns: ["countryName", "monthlyTargetHours"],
notes: ["SAH is holiday-adjusted."],
},
(column) => ({
countryCode: "Country Code",
federalState: "Federal State",
monthlyPublicHolidayCount: "Holiday Dates",
monthlyAbsenceHoursDeduction: "Absence Hours Deduction",
monthlyBaseAvailableHours: "Base Available Hours",
monthlySahHours: "SAH",
monthlyActualChargeabilityPct: "Actual Chargeability (%)",
countryName: "Country",
monthlyTargetHours: "Target Hours",
}[column] ?? column),
);
expect(rows).toEqual([
["Resource Month Explainability"],
["Period Month", "2026-01"],
["Location Context Columns", "Country Code", "Federal State"],
["Holiday Metric Columns", "Holiday Dates"],
["Absence Metric Columns", "Absence Hours Deduction"],
["Capacity Metric Columns", "Base Available Hours", "SAH"],
["Chargeability Metric Columns", "Actual Chargeability (%)"],
["Missing Recommended Columns", "Country", "Target Hours"],
[],
["Notes"],
["SAH is holiday-adjusted."],
]);
});
it("adds grouped report rows and an explainability sheet to workbook output", () => {
const sheets = buildReportWorkbookSheets({
columns: ["displayName", "monthlySahHours"],
rows: [
{ displayName: "Alice", monthlySahHours: 160 },
{ displayName: "Bob", monthlySahHours: 152 },
],
groups: [{ key: "BY", label: "Bayern", rowCount: 2, startIndex: 0 }],
groupBy: "federalState",
explainability: {
entity: "resource_month",
periodMonth: "2026-01",
locationContextColumns: [],
holidayMetricColumns: [],
absenceMetricColumns: [],
capacityMetricColumns: [],
chargeabilityMetricColumns: [],
missingRecommendedColumns: [],
notes: [],
},
resolveColumnLabel: (column) => ({
displayName: "Name",
monthlySahHours: "SAH",
federalState: "Federal State",
}[column] ?? column),
});
expect(sheets[0]).toEqual({
name: "Report",
rows: [
["Name", "SAH"],
["Federal State: Bayern (2)", ""],
["Alice", 160],
["Bob", 152],
],
});
expect(sheets[1]?.name).toBe("Explainability");
});
});
@@ -0,0 +1,91 @@
type WorkbookCellValue = boolean | Date | number | string | null | undefined;
export type ResourceMonthReportExplainability = {
entity: "resource_month";
periodMonth: string | null;
locationContextColumns: string[];
holidayMetricColumns: string[];
absenceMetricColumns: string[];
capacityMetricColumns: string[];
chargeabilityMetricColumns: string[];
missingRecommendedColumns: string[];
notes: string[];
};
export type ReportExplainability = ResourceMonthReportExplainability;
export type ReportExportSheet = {
name: string;
rows: WorkbookCellValue[][];
};
type BuildReportWorkbookSheetsInput = {
columns: string[];
rows: Record<string, unknown>[];
groups: Array<{ key: string; label: string; rowCount: number; startIndex: number }>;
groupBy?: string;
explainability?: ReportExplainability;
resolveColumnLabel: (column: string) => string;
};
export function buildResourceMonthExplainabilitySheetRows(
explainability: ReportExplainability,
resolveColumnLabel: (column: string) => string,
): WorkbookCellValue[][] {
const mapLabels = (columns: string[]) => (
columns.length > 0 ? columns.map(resolveColumnLabel) : ["none"]
);
return [
["Resource Month Explainability"],
["Period Month", explainability.periodMonth ?? "current month"],
["Location Context Columns", ...mapLabels(explainability.locationContextColumns)],
["Holiday Metric Columns", ...mapLabels(explainability.holidayMetricColumns)],
["Absence Metric Columns", ...mapLabels(explainability.absenceMetricColumns)],
["Capacity Metric Columns", ...mapLabels(explainability.capacityMetricColumns)],
["Chargeability Metric Columns", ...mapLabels(explainability.chargeabilityMetricColumns)],
["Missing Recommended Columns", ...mapLabels(explainability.missingRecommendedColumns)],
[],
["Notes"],
...explainability.notes.map((note) => [note]),
];
}
export function buildReportWorkbookSheets(
input: BuildReportWorkbookSheetsInput,
): ReportExportSheet[] {
const headerRow = input.columns.map(input.resolveColumnLabel);
const groupStartByIndex = new Map(
input.groups.map((group) => [group.startIndex, group] as const),
);
const groupByLabel = input.groupBy ? input.resolveColumnLabel(input.groupBy) : null;
const reportRows: WorkbookCellValue[][] = [headerRow];
input.rows.forEach((row, index) => {
const group = groupStartByIndex.get(index);
if (group && groupByLabel) {
reportRows.push([
`${groupByLabel}: ${group.label} (${group.rowCount})`,
...Array.from({ length: Math.max(0, input.columns.length - 1) }, () => ""),
]);
}
reportRows.push(input.columns.map((column) => {
const value = row[column];
if (value === undefined) {
return "";
}
return value as WorkbookCellValue;
}));
});
const sheets: ReportExportSheet[] = [{ name: "Report", rows: reportRows }];
if (input.explainability?.entity === "resource_month") {
sheets.push({
name: "Explainability",
rows: buildResourceMonthExplainabilitySheetRows(input.explainability, input.resolveColumnLabel),
});
}
return sheets;
}