import { AllocationStatus } from "@capakraken/shared"; import { describe, expect, it, vi } from "vitest"; import { createAssignment, updateAssignment, updateDemandRequirement, } from "../index.js"; describe("allocation entry update flows", () => { it("excludes the current assignment from conflict checks during update", async () => { const projectFindUnique = vi.fn().mockResolvedValue({ id: "project_1" }); const resourceFindUnique = vi.fn().mockResolvedValue({ id: "resource_1", lcrCents: 5000, availability: { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8, saturday: 0, sunday: 0, }, }); const assignmentFindMany = vi.fn().mockResolvedValue([]); const vacationFindMany = vi.fn().mockResolvedValue([]); const assignmentCreate = vi.fn().mockResolvedValue({ id: "assignment_1", demandRequirementId: null, resourceId: "resource_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "Compositor", roleId: "role_comp", dailyCostCents: 20000, status: AllocationStatus.PROPOSED, metadata: {}, createdAt: new Date("2026-03-13"), updatedAt: new Date("2026-03-13"), resource: { id: "resource_1", displayName: "Alice", eid: "E-001", lcrCents: 5000 }, project: { id: "project_1", name: "Project One", shortCode: "PRJ" }, roleEntity: { id: "role_comp", name: "Compositor", color: "#111111" }, demandRequirement: null, }); const auditLogCreate = vi.fn().mockResolvedValue({}); await createAssignment( { project: { findUnique: projectFindUnique }, resource: { findUnique: resourceFindUnique }, assignment: { findMany: assignmentFindMany, create: assignmentCreate }, vacation: { findMany: vacationFindMany }, auditLog: { create: auditLogCreate }, } as never, { resourceId: "resource_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "Compositor", roleId: "role_comp", status: AllocationStatus.PROPOSED, metadata: {}, }, ); expect(assignmentFindMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.objectContaining({ resourceId: { in: ["resource_1"] }, status: { not: "CANCELLED" }, }), }), ); }); it("updates a linked demand requirement directly", async () => { const demandRequirementFindUnique = vi.fn().mockResolvedValue({ id: "demand_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "FX Artist", roleId: "role_fx", headcount: 2, status: AllocationStatus.PROPOSED, project: { id: "project_1", name: "Project One", shortCode: "PRJ" }, roleEntity: { id: "role_fx", name: "FX Artist", color: "#222222" }, }); const demandRequirementUpdate = vi.fn().mockResolvedValue({ id: "demand_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "FX Artist", roleId: "role_fx", headcount: 1, status: AllocationStatus.COMPLETED, project: { id: "project_1", name: "Project One", shortCode: "PRJ" }, roleEntity: { id: "role_fx", name: "FX Artist", color: "#222222" }, }); const auditLogCreate = vi.fn().mockResolvedValue({}); const result = await updateDemandRequirement( { demandRequirement: { findUnique: demandRequirementFindUnique, update: demandRequirementUpdate, }, auditLog: { create: auditLogCreate }, } as never, "demand_1", { headcount: 1, status: AllocationStatus.COMPLETED, metadata: { source: "update-test" }, }, ); expect(result.headcount).toBe(1); expect(auditLogCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ entityType: "DemandRequirement", entityId: "demand_1", }), }), ); }); it("updates a linked assignment directly", async () => { const existingAssignment = { id: "assignment_1", demandRequirementId: "demand_1", resourceId: "resource_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "Compositor", roleId: "role_comp", dailyCostCents: 20000, status: AllocationStatus.PROPOSED, resource: { id: "resource_1", displayName: "Alice", eid: "E-001", lcrCents: 5000 }, project: { id: "project_1", name: "Project One", shortCode: "PRJ" }, roleEntity: { id: "role_comp", name: "Compositor", color: "#111111" }, demandRequirement: { id: "demand_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "Compositor", roleId: "role_comp", headcount: 1, status: AllocationStatus.PROPOSED, }, }; const assignmentFindUnique = vi.fn().mockResolvedValue(existingAssignment); const assignmentUpdate = vi.fn().mockResolvedValue({ ...existingAssignment, id: "assignment_1", demandRequirementId: "demand_1", resourceId: "resource_1", projectId: "project_1", startDate: new Date("2026-03-17"), endDate: new Date("2026-03-28"), hoursPerDay: 6, percentage: 75, role: "Lead Compositor", roleId: "role_lead_comp", dailyCostCents: 32000, status: AllocationStatus.CONFIRMED, metadata: { source: "update-test" }, resource: { id: "resource_1", displayName: "Alice", eid: "E-001", lcrCents: 5000 }, project: { id: "project_1", name: "Project One", shortCode: "PRJ" }, roleEntity: { id: "role_lead_comp", name: "Lead Compositor", color: "#444444" }, demandRequirement: { id: "demand_1", projectId: "project_1", startDate: new Date("2026-03-16"), endDate: new Date("2026-03-27"), hoursPerDay: 4, percentage: 50, role: "Compositor", roleId: "role_comp", headcount: 1, status: AllocationStatus.PROPOSED, }, }); const auditLogCreate = vi.fn().mockResolvedValue({}); const result = await updateAssignment( { assignment: { findUnique: assignmentFindUnique, update: assignmentUpdate, }, auditLog: { create: auditLogCreate }, } as never, "assignment_1", { startDate: new Date("2026-03-17"), endDate: new Date("2026-03-28"), hoursPerDay: 6, percentage: 75, role: "Lead Compositor", roleId: "role_lead_comp", dailyCostCents: 32000, status: AllocationStatus.CONFIRMED, metadata: { source: "update-test" }, }, ); expect(result.dailyCostCents).toBe(32000); expect(auditLogCreate).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ entityType: "Assignment", entityId: "assignment_1", }), }), ); }); });