From f2d65d3cd4ad16edf1f58676fecfebeeb2b584c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Wed, 1 Apr 2026 00:51:23 +0200 Subject: [PATCH] test(api): add assistant split regression runner --- docs/assistant-tool-test-split-migration.md | 151 ++++++++++++++++++ packages/api/package.json | 3 +- .../run-assistant-tool-split-regression.mjs | 106 ++++++++++++ 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 docs/assistant-tool-test-split-migration.md create mode 100644 packages/api/scripts/run-assistant-tool-split-regression.mjs diff --git a/docs/assistant-tool-test-split-migration.md b/docs/assistant-tool-test-split-migration.md new file mode 100644 index 0000000..3d3d5d6 --- /dev/null +++ b/docs/assistant-tool-test-split-migration.md @@ -0,0 +1,151 @@ +# Assistant Tool Test Split Migration + +Stand: 2026-04-01 + +Diese Notiz hält fest, wie die alten Assistant-Tool-Monolith-Tests in kleinere, fachlich geschnittene Suiten aufgeteilt wurden und wie die Regression dafür reproduzierbar ausgeführt wird. + +## Ziel + +- Alte Sammeltests waren konfliktanfällig und schwer gezielt zu regressieren. +- Neue Split-Tests schneiden entlang fachlicher Domänen und realer Access-/Mutation-Verträge. +- Die Regression soll explizit und reproduzierbar laufen, statt implizit über breite Dateiglob-Matches. + +## Regression ausführen + +Im Paket `@capakraken/api`: + +```bash +pnpm test:assistant-split +``` + +Der Runner führt fünf explizite Vitest-Batches plus abschließenden API-Typecheck aus: + +1. Allocation und Quick Assign +2. Timeline und Advanced Ranking +3. Dispo +4. Estimate +5. Insights und Misc + +## Legacy-zu-Split-Mapping + +### `assistant-tool-policy.test.ts` + +Aufgeteilt in: + +- `assistant-tool-policy-access.test.ts` +- `assistant-tool-policy-admin.test.ts` +- `assistant-tool-policy-planning.test.ts` +- ergänzend domänische Guards in `assistant-tools-auth-guard.test.ts` + +Abgedeckt werden damit insbesondere: + +- Sichtbarkeit von Tools je Rolle +- Permission-Gates für Planning, Costs und `useAssistantAdvancedTools` +- Trennung zwischen Self-Service, Admin- und Controller-Surface + +### `assistant-tools-advanced.test.ts` + +Aufgeteilt in: + +- `assistant-tools-advanced-resource-ranking.test.ts` +- `assistant-tools-advanced-timeline-entries-view.test.ts` +- `assistant-tools-advanced-project-timeline-context.test.ts` +- `assistant-tools-advanced-project-shift-preview.test.ts` +- `assistant-tools-timeline-resource-selection.test.ts` + +Abgedeckt werden damit insbesondere: + +- Advanced-Ranking und Project-Resource-Selection +- Timeline-Readmodels und Shift-Preview +- Access-Gates für `viewPlanning`, `viewCosts` und `useAssistantAdvancedTools` + +### `assistant-tools-audit.test.ts` + +Aufgeteilt in: + +- `assistant-tools-audit-log-list.test.ts` +- `assistant-tools-audit-read.test.ts` +- `assistant-tools-audit-entity-summary.test.ts` +- `assistant-tools-audit-errors-auth.test.ts` +- ergänzend `assistant-tools-query-change-history.test.ts` + +Abgedeckt werden damit insbesondere: + +- Listen-, Detail- und Summary-Reads +- stabile Auth-/Role-Fehler für Controller-only Reads +- Query-Change-History als separates Controller-Readmodel + +### `assistant-tools-country.test.ts` + +Aufgeteilt in: + +- `assistant-tools-country-list.test.ts` +- `assistant-tools-country-get.test.ts` +- `assistant-tools-country-mutations-success.test.ts` +- `assistant-tools-country-mutations-errors.test.ts` +- `assistant-tools-metro-city-mutations-success.test.ts` +- `assistant-tools-metro-city-mutations-errors.test.ts` + +Abgedeckt werden damit insbesondere: + +- Country-Readmodels +- Fehleroberflächen für Not Found und Duplikate +- Country- und Metro-City-Mutationen + +Hinweis: +`get_country` verlangt inzwischen explizit `VIEW_ALL_RESOURCES`; die neuen Split-Tests sind an diesem aktuellen Vertrag ausgerichtet. + +### `assistant-tools-holidays.test.ts` + +Aufgeteilt in: + +- `assistant-tools-holiday-calendar-get.test.ts` +- `assistant-tools-holiday-calendar-get-errors.test.ts` +- `assistant-tools-holiday-calendars-list.test.ts` +- `assistant-tools-holiday-calendar-mutations-success.test.ts` +- `assistant-tools-holiday-calendar-mutations-guards.test.ts` +- `assistant-tools-holiday-entry-mutations-success.test.ts` +- `assistant-tools-holiday-entry-mutations-errors.test.ts` +- `assistant-tools-holiday-resolution-calendar-preview.test.ts` +- `assistant-tools-holiday-resolution-regional-resource.test.ts` +- `assistant-tools-holiday-capacity.test.ts` +- `assistant-tools-holiday-chargeability.test.ts` +- `assistant-tools-holiday-budget-shoring.test.ts` +- `assistant-tools-holiday-simulation.test.ts` +- `assistant-tools-holiday-staffing-suggestions.test.ts` + +Abgedeckt werden damit insbesondere: + +- Holiday-Calendars und deren CRUD +- Region-/Resource-spezifische Auflösung +- Holiday-Einfluss auf Capacity, Chargeability, Budget und Staffing + +### `assistant-tools-import-export.test.ts` + +Aufgeteilt in: + +- `assistant-tools-import.test.ts` +- `assistant-tools-export.test.ts` +- `assistant-tools-dispo-import.test.ts` +- `assistant-tools-dispo-import-batch-list-cancel.test.ts` +- `assistant-tools-dispo-import-batch-delegation.test.ts` +- `assistant-tools-dispo-staged-listings-resources-projects.test.ts` +- `assistant-tools-dispo-staged-unresolved-read.test.ts` +- `assistant-tools-dispo-staged-vacations-read.test.ts` +- `assistant-tools-dispo-staged-assignments-read.test.ts` +- `assistant-tools-dispo-staged-resolution.test.ts` + +Abgedeckt werden damit insbesondere: + +- CSV-Import-/Export-Pfade +- Permission-Gates wie `importData` +- Dispo-Import-Staging, Delegation, Commit und Cancel + +## Verifikationsstand + +Der aktuelle Split-Runner wurde gegen die genannten Batches und den API-Typecheck validiert. + +Bewusst noch nicht Teil dieses Dokuments: + +- konfliktträchtige, bereits separat bearbeitete Notification-/Timeline-Support-Dateien +- breit gefächerte Repo-weite Vitest-Globs, weil diese in der Vergangenheit versehentlich mehr als die Ziel-Suite eingesammelt haben diff --git a/packages/api/package.json b/packages/api/package.json index 7c5d533..22e2e7a 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -15,7 +15,8 @@ }, "scripts": { "typecheck": "tsc --noEmit", - "test:unit": "vitest run" + "test:unit": "vitest run", + "test:assistant-split": "node ./scripts/run-assistant-tool-split-regression.mjs" }, "dependencies": { "@capakraken/application": "workspace:*", diff --git a/packages/api/scripts/run-assistant-tool-split-regression.mjs b/packages/api/scripts/run-assistant-tool-split-regression.mjs new file mode 100644 index 0000000..3bd594c --- /dev/null +++ b/packages/api/scripts/run-assistant-tool-split-regression.mjs @@ -0,0 +1,106 @@ +import { spawnSync } from "node:child_process"; + +const batches = [ + { + name: "allocation-and-quick-assign", + files: [ + "src/__tests__/assistant-tools-allocation-create-success.test.ts", + "src/__tests__/assistant-tools-allocation-create-errors.test.ts", + "src/__tests__/assistant-tools-allocation-status-success.test.ts", + "src/__tests__/assistant-tools-allocation-status-errors.test.ts", + "src/__tests__/assistant-tools-allocation-cancel-success.test.ts", + "src/__tests__/assistant-tools-allocation-cancel-errors.test.ts", + "src/__tests__/assistant-tools-timeline-quick-assign-success.test.ts", + "src/__tests__/assistant-tools-timeline-quick-assign-errors.test.ts", + "src/__tests__/assistant-tools-timeline-batch-quick-assign-success.test.ts", + "src/__tests__/assistant-tools-timeline-batch-quick-assign-errors.test.ts", + ], + }, + { + name: "timeline-and-advanced-ranking", + files: [ + "src/__tests__/assistant-tools-timeline-allocation-shifts.test.ts", + "src/__tests__/assistant-tools-timeline-allocation-shift-errors.test.ts", + "src/__tests__/assistant-tools-timeline-inline-allocation-update-success.test.ts", + "src/__tests__/assistant-tools-timeline-inline-allocation-update-errors.test.ts", + "src/__tests__/assistant-tools-timeline-project-shifts.test.ts", + "src/__tests__/assistant-tools-timeline-resource-selection.test.ts", + "src/__tests__/assistant-tools-advanced-resource-ranking.test.ts", + "src/__tests__/assistant-tools-advanced-timeline-entries-view.test.ts", + "src/__tests__/assistant-tools-advanced-project-timeline-context.test.ts", + "src/__tests__/assistant-tools-advanced-project-shift-preview.test.ts", + ], + }, + { + name: "dispo", + files: [ + "src/__tests__/assistant-tools-dispo-staged-listings-resources-projects.test.ts", + "src/__tests__/assistant-tools-dispo-staged-unresolved-read.test.ts", + "src/__tests__/assistant-tools-dispo-staged-vacations-read.test.ts", + "src/__tests__/assistant-tools-dispo-staged-assignments-read.test.ts", + "src/__tests__/assistant-tools-dispo-staged-resolution.test.ts", + "src/__tests__/assistant-tools-dispo-import.test.ts", + "src/__tests__/assistant-tools-dispo-import-batch-list-cancel.test.ts", + "src/__tests__/assistant-tools-dispo-import-batch-delegation.test.ts", + ], + }, + { + name: "estimate", + files: [ + "src/__tests__/assistant-tools-estimate-read-detail-access.test.ts", + "src/__tests__/assistant-tools-estimate-read-not-found.test.ts", + "src/__tests__/assistant-tools-estimate-read-version-snapshot-access.test.ts", + "src/__tests__/assistant-tools-estimate-read-versions-list-access.test.ts", + "src/__tests__/assistant-tools-estimate-clone-errors.test.ts", + "src/__tests__/assistant-tools-estimate-commercial-terms-errors.test.ts", + "src/__tests__/assistant-tools-estimate-creation-races.test.ts", + "src/__tests__/assistant-tools-estimate-draft-errors.test.ts", + "src/__tests__/assistant-tools-estimate-generate-weekly-phasing-errors.test.ts", + "src/__tests__/assistant-tools-estimate-get-weekly-phasing-errors.test.ts", + "src/__tests__/assistant-tools-estimate-planning-handoff-errors.test.ts", + "src/__tests__/assistant-tools-estimate-revision-export-errors.test.ts", + "src/__tests__/assistant-tools-estimate-version-status-errors.test.ts", + ], + }, + { + name: "insights-and-misc", + files: [ + "src/__tests__/assistant-tools-insights-summary.test.ts", + "src/__tests__/assistant-tools-insights-anomalies.test.ts", + "src/__tests__/assistant-tools-scenarios.test.ts", + "src/__tests__/assistant-tools-budget-status.test.ts", + "src/__tests__/assistant-tools-chargeability-report.test.ts", + "src/__tests__/assistant-tools-auth-guard.test.ts", + "src/__tests__/assistant-tools-master-data-rate-lookup.test.ts", + "src/__tests__/assistant-tools-query-change-history.test.ts", + "src/__tests__/assistant-tools-project-cover-generate.test.ts", + "src/__tests__/assistant-tools-project-cover-remove.test.ts", + "src/__tests__/assistant-tools-project-narrative.test.ts", + "src/__tests__/assistant-tools-project-computation-graph.test.ts", + "src/__tests__/assistant-tools-resource-computation-graph.test.ts", + "src/__tests__/assistant-tools-settings-role-config-admin.test.ts", + "src/__tests__/assistant-tools-import.test.ts", + "src/__tests__/assistant-tools-export.test.ts", + "src/__tests__/ai-client.test.ts", + ], + }, +]; + +function run(command, args) { + const result = spawnSync(command, args, { + cwd: new URL("..", import.meta.url), + stdio: "inherit", + shell: process.platform === "win32", + }); + if (result.status !== 0) { + process.exit(result.status ?? 1); + } +} + +for (const batch of batches) { + console.log(`\n== assistant split regression: ${batch.name} ==`); + run("pnpm", ["exec", "vitest", "run", ...batch.files]); +} + +console.log("\n== assistant split regression: typecheck =="); +run("pnpm", ["exec", "tsc", "-p", "tsconfig.json", "--noEmit", "--pretty", "false"]);