55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
import { PermissionKey } from "@capakraken/shared";
|
|
import { z } from "zod";
|
|
import { createTRPCRouter, controllerProcedure, planningReadProcedure, requirePermission } from "../trpc.js";
|
|
import { applyProjectScenario } from "./scenario-apply.js";
|
|
import { readProjectScenarioBaseline } from "./scenario-baseline.js";
|
|
import { simulateProjectScenario } from "./scenario-simulation.js";
|
|
|
|
const ScenarioChangeSchema = z.object({
|
|
/** Existing assignment to modify — omit to add a new allocation */
|
|
assignmentId: z.string().optional(),
|
|
resourceId: z.string().optional(),
|
|
roleId: z.string().optional(),
|
|
startDate: z.coerce.date(),
|
|
endDate: z.coerce.date(),
|
|
hoursPerDay: z.number().min(0).max(24),
|
|
/** Set to true to mark an existing assignment for removal */
|
|
remove: z.boolean().optional(),
|
|
});
|
|
|
|
const SimulateInputSchema = z.object({
|
|
projectId: z.string(),
|
|
changes: z.array(ScenarioChangeSchema).min(1),
|
|
});
|
|
|
|
export const scenarioRouter = createTRPCRouter({
|
|
/**
|
|
* Returns current allocations/costs for a project — the baseline for comparison.
|
|
*/
|
|
getProjectBaseline: planningReadProcedure
|
|
.input(z.object({ projectId: z.string() }))
|
|
.query(async ({ ctx, input }) => {
|
|
requirePermission(ctx, PermissionKey.VIEW_COSTS);
|
|
return readProjectScenarioBaseline(ctx.db, input.projectId);
|
|
}),
|
|
|
|
/**
|
|
* Pure simulation: computes cost/hours/utilization impact of scenario changes
|
|
* without persisting anything.
|
|
*/
|
|
simulate: controllerProcedure
|
|
.input(SimulateInputSchema)
|
|
.mutation(async ({ ctx, input }) => simulateProjectScenario(ctx.db, input)),
|
|
|
|
/**
|
|
* Applies a scenario: creates real assignments from scenario changes.
|
|
* Manager+ access required.
|
|
*/
|
|
applyScenario: controllerProcedure
|
|
.input(SimulateInputSchema)
|
|
.mutation(async ({ ctx, input }) => applyProjectScenario(ctx.db, {
|
|
...input,
|
|
userId: ctx.dbUser?.id,
|
|
})),
|
|
});
|