import { beforeEach, describe, expect, it, vi } from "vitest"; import { PermissionKey, SystemRole } from "@capakraken/shared"; vi.mock("@capakraken/application", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, approveEstimateVersion: vi.fn(), cloneEstimate: vi.fn(), commitDispoImportBatch: vi.fn(), countPlanningEntries: vi.fn().mockResolvedValue({ countsByRoleId: new Map() }), createEstimateExport: vi.fn(), createEstimatePlanningHandoff: vi.fn(), createEstimateRevision: vi.fn(), assessDispoImportReadiness: vi.fn(), loadResourceDailyAvailabilityContexts: vi.fn().mockResolvedValue(new Map()), getDashboardDemand: vi.fn().mockResolvedValue([]), getDashboardBudgetForecast: vi.fn().mockResolvedValue([]), getDashboardOverview: vi.fn(), getDashboardSkillGapSummary: vi.fn().mockResolvedValue({ roleGaps: [], totalOpenPositions: 0, skillSupplyTop10: [], resourcesByRole: [], }), getDashboardProjectHealth: vi.fn().mockResolvedValue([]), getDashboardPeakTimes: vi.fn().mockResolvedValue([]), getDashboardTopValueResources: vi.fn().mockResolvedValue([]), getEstimateById: vi.fn(), listAssignmentBookings: vi.fn().mockResolvedValue([]), stageDispoImportBatch: vi.fn(), submitEstimateVersion: vi.fn(), updateEstimateDraft: vi.fn(), }; }); import { executeTool } from "../router/assistant-tools.js"; import { createToolContext } from "./assistant-tools-planning-read-test-helpers.js"; describe("assistant planning allocation and vacation read tools", () => { beforeEach(() => { vi.clearAllMocks(); }); it("routes allocation listing through the allocation router path", async () => { const db = { systemSettings: { findUnique: vi.fn().mockResolvedValue({ anonymizationEnabled: false, anonymizationDomain: null, anonymizationSeed: null, anonymizationMode: null, anonymizationAliases: null, }), }, demandRequirement: { findMany: vi.fn().mockResolvedValue([ { id: "demand_1", projectId: "project_1", startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-30T00:00:00.000Z"), hoursPerDay: 8, percentage: 100, role: "TD", roleId: null, headcount: 1, status: "OPEN", metadata: null, createdAt: new Date("2026-03-20T00:00:00.000Z"), updatedAt: new Date("2026-03-20T00:00:00.000Z"), project: { id: "project_1", name: "Gelddruckmaschine", shortCode: "GDM", status: "ACTIVE", endDate: new Date("2026-04-30T00:00:00.000Z"), }, roleEntity: null, assignments: [], }, ]), }, assignment: { findMany: vi.fn().mockResolvedValue([ { id: "assign_1", demandRequirementId: null, resourceId: "res_1", projectId: "project_1", startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-10T00:00:00.000Z"), hoursPerDay: 6, percentage: 75, role: "Pipeline TD", roleId: null, dailyCostCents: 12_000, status: "ACTIVE", metadata: null, createdAt: new Date("2026-03-21T00:00:00.000Z"), updatedAt: new Date("2026-03-21T00:00:00.000Z"), resource: { id: "res_1", displayName: "Bruce Banner", eid: "EMP-001", lcrCents: 8_500, }, project: { id: "project_1", name: "Gelddruckmaschine", shortCode: "GDM", status: "ACTIVE", endDate: new Date("2026-04-30T00:00:00.000Z"), }, roleEntity: null, demandRequirement: null, }, ]), }, }; const ctx = createToolContext(db, { userRole: SystemRole.CONTROLLER, permissions: [PermissionKey.VIEW_PLANNING], }); const result = await executeTool( "list_allocations", JSON.stringify({ projectId: "project_1", resourceName: "Bruce", projectCode: "GDM", status: "ACTIVE", limit: 10, }), ctx, ); expect(db.demandRequirement.findMany).toHaveBeenCalledWith({ where: { projectId: "project_1", status: "ACTIVE", }, include: { project: { select: { id: true, name: true, shortCode: true, status: true, endDate: true, }, }, roleEntity: { select: { id: true, name: true, color: true }, }, assignments: { include: { resource: { select: { id: true, displayName: true, eid: true, lcrCents: true, chapter: true, }, }, project: { select: { id: true, name: true, shortCode: true, status: true, endDate: true, }, }, roleEntity: { select: { id: true, name: true, color: true }, }, }, }, }, orderBy: { startDate: "asc" }, }); expect(db.assignment.findMany).toHaveBeenCalledWith({ where: { projectId: "project_1", status: "ACTIVE", }, include: { resource: { select: { id: true, displayName: true, eid: true, lcrCents: true, chapter: true, }, }, project: { select: { id: true, name: true, shortCode: true, status: true, endDate: true, }, }, roleEntity: { select: { id: true, name: true, color: true }, }, demandRequirement: { select: { id: true, projectId: true, startDate: true, endDate: true, hoursPerDay: true, percentage: true, role: true, roleId: true, headcount: true, status: true, }, }, }, orderBy: { startDate: "asc" }, }); expect(JSON.parse(result.content)).toEqual([ { id: "assign_1", resource: "Bruce Banner", resourceEid: "EMP-001", project: "Gelddruckmaschine", projectCode: "GDM", role: "Pipeline TD", status: "ACTIVE", hoursPerDay: 6, dailyCost: "120,00 EUR", start: "2026-04-01", end: "2026-04-10", }, ]); }); });