refactor(api): extract project computation graph snapshot loading
This commit is contained in:
@@ -4,92 +4,21 @@ import {
|
||||
distributeHoursToWeeks,
|
||||
summarizeEstimateDemandLines,
|
||||
} from "@capakraken/engine";
|
||||
import type { TRPCContext } from "../trpc.js";
|
||||
import { fmtEur } from "../lib/format-utils.js";
|
||||
import { loadProjectGraphSnapshot, type ProjectGraphInput } from "./computation-graph-project-snapshot.js";
|
||||
import { type GraphLink, type GraphNode, fmtNum, l, n } from "./computation-graph-shared.js";
|
||||
|
||||
type ProjectGraphInput = {
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
export async function readProjectGraphSnapshot(
|
||||
ctx: { db: TRPCContext["db"] },
|
||||
ctx: Parameters<typeof loadProjectGraphSnapshot>[0],
|
||||
input: ProjectGraphInput,
|
||||
) {
|
||||
const project = await ctx.db.project.findUniqueOrThrow({
|
||||
where: { id: input.projectId },
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
shortCode: true,
|
||||
budgetCents: true,
|
||||
winProbability: true,
|
||||
startDate: true,
|
||||
endDate: true,
|
||||
},
|
||||
});
|
||||
|
||||
const estimate = await ctx.db.estimate.findFirst({
|
||||
where: { projectId: input.projectId },
|
||||
select: {
|
||||
id: true,
|
||||
versions: {
|
||||
orderBy: { versionNumber: "desc" },
|
||||
take: 1,
|
||||
select: {
|
||||
id: true,
|
||||
commercialTerms: true,
|
||||
demandLines: {
|
||||
select: {
|
||||
id: true,
|
||||
hours: true,
|
||||
costRateCents: true,
|
||||
billRateCents: true,
|
||||
costTotalCents: true,
|
||||
priceTotalCents: true,
|
||||
chapter: true,
|
||||
monthlySpread: true,
|
||||
scopeItemId: true,
|
||||
resourceId: true,
|
||||
},
|
||||
},
|
||||
scopeItems: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
scopeType: true,
|
||||
frameCount: true,
|
||||
itemCount: true,
|
||||
unitMode: true,
|
||||
},
|
||||
},
|
||||
resourceSnapshots: {
|
||||
select: {
|
||||
id: true,
|
||||
resourceId: true,
|
||||
displayName: true,
|
||||
chapter: true,
|
||||
lcrCents: true,
|
||||
ucrCents: true,
|
||||
location: true,
|
||||
level: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { updatedAt: "desc" },
|
||||
});
|
||||
const latestVersion = estimate?.versions[0];
|
||||
|
||||
let effortRuleCount = 0;
|
||||
let experienceRuleCount = 0;
|
||||
try {
|
||||
effortRuleCount = await ctx.db.effortRule.count();
|
||||
experienceRuleCount = await ctx.db.experienceMultiplierRule.count();
|
||||
} catch {
|
||||
// tables may not exist yet
|
||||
}
|
||||
const {
|
||||
project,
|
||||
latestVersion,
|
||||
effortRuleCount,
|
||||
experienceRuleCount,
|
||||
projectAllocations,
|
||||
} = await loadProjectGraphSnapshot(ctx, input);
|
||||
|
||||
const nodes: GraphNode[] = [];
|
||||
const links: GraphLink[] = [];
|
||||
@@ -328,11 +257,6 @@ export async function readProjectGraphSnapshot(
|
||||
}
|
||||
}
|
||||
|
||||
const projectAllocations = await ctx.db.assignment.findMany({
|
||||
where: { projectId: input.projectId },
|
||||
select: { status: true, dailyCostCents: true, startDate: true, endDate: true, hoursPerDay: true },
|
||||
});
|
||||
|
||||
if (projectAllocations.length > 0) {
|
||||
const budgetStatus = computeBudgetStatus(
|
||||
project.budgetCents,
|
||||
|
||||
Reference in New Issue
Block a user