cd78f72f33
Complete rename of all technical identifiers across the codebase: Package names (11 packages): - @planarchy/* → @capakraken/* in all package.json, tsconfig, imports Import statements: 277 files, 548 occurrences replaced Database & Docker: - PostgreSQL user/db: planarchy → capakraken - Docker volumes: planarchy_pgdata → capakraken_pgdata - Connection strings updated in docker-compose, .env, CI CI/CD: - GitHub Actions workflow: all filter commands updated - Test database credentials updated Infrastructure: - Redis channel: planarchy:sse → capakraken:sse - Logger service name: planarchy-api → capakraken-api - Anonymization seed updated - Start/stop/restart scripts updated Test data: - Seed emails: @planarchy.dev → @capakraken.dev - E2E test credentials: all 11 spec files updated - Email defaults: @planarchy.app → @capakraken.app - localStorage keys: planarchy_* → capakraken_* Documentation: 30+ .md files updated Verification: - pnpm install: workspace resolution works - TypeScript: only pre-existing TS2589 (no new errors) - Engine: 310/310 tests pass - Staffing: 37/37 tests pass Co-Authored-By: claude-flow <ruv@ruv.net>
238 lines
7.5 KiB
TypeScript
238 lines
7.5 KiB
TypeScript
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",
|
|
}),
|
|
}),
|
|
);
|
|
});
|
|
|
|
});
|