refactor(api): extract computation graph procedures
This commit is contained in:
@@ -27,6 +27,7 @@ Done
|
|||||||
- `calculation-rules`
|
- `calculation-rules`
|
||||||
- `webhook`
|
- `webhook`
|
||||||
- `role`
|
- `role`
|
||||||
|
- `computation-graph`
|
||||||
|
|
||||||
Ready next
|
Ready next
|
||||||
- none in the conflict-safe backlog
|
- none in the conflict-safe backlog
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import {
|
||||||
|
getProjectGraphData,
|
||||||
|
getResourceGraphData,
|
||||||
|
} from "../router/computation-graph-procedure-support.js";
|
||||||
|
|
||||||
|
const { readResourceGraphSnapshot, readProjectGraphSnapshot } = vi.hoisted(() => ({
|
||||||
|
readResourceGraphSnapshot: vi.fn(),
|
||||||
|
readProjectGraphSnapshot: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../router/computation-graph-resource.js", () => ({
|
||||||
|
readResourceGraphSnapshot,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../router/computation-graph-project.js", () => ({
|
||||||
|
readProjectGraphSnapshot,
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("computation-graph-procedure-support", () => {
|
||||||
|
it("delegates resource graph reads to the snapshot reader", async () => {
|
||||||
|
const ctx = { db: {} } as never;
|
||||||
|
const snapshot = { nodes: [], links: [], meta: { resourceEid: "eid", resourceName: "Bruce" } };
|
||||||
|
readResourceGraphSnapshot.mockResolvedValue(snapshot);
|
||||||
|
|
||||||
|
const result = await getResourceGraphData(ctx, {
|
||||||
|
resourceId: "resource_1",
|
||||||
|
month: "2026-01",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBe(snapshot);
|
||||||
|
expect(readResourceGraphSnapshot).toHaveBeenCalledWith(ctx, {
|
||||||
|
resourceId: "resource_1",
|
||||||
|
month: "2026-01",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("delegates project graph reads to the snapshot reader", async () => {
|
||||||
|
const ctx = { db: {} } as never;
|
||||||
|
const snapshot = { nodes: [], links: [], meta: { projectCode: "GDM", projectName: "Gelddruckmaschine" } };
|
||||||
|
readProjectGraphSnapshot.mockResolvedValue(snapshot);
|
||||||
|
|
||||||
|
const result = await getProjectGraphData(ctx, {
|
||||||
|
projectId: "project_1",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toBe(snapshot);
|
||||||
|
expect(readProjectGraphSnapshot).toHaveBeenCalledWith(ctx, {
|
||||||
|
projectId: "project_1",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import type { TRPCContext } from "../trpc.js";
|
||||||
|
import { createComputationGraphDetailProcedures } from "./computation-graph-detail.js";
|
||||||
|
import { readProjectGraphSnapshot } from "./computation-graph-project.js";
|
||||||
|
import { readResourceGraphSnapshot } from "./computation-graph-resource.js";
|
||||||
|
|
||||||
|
export const ResourceGraphInputSchema = z.object({
|
||||||
|
resourceId: z.string(),
|
||||||
|
month: z.string().regex(/^\d{4}-\d{2}$/),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ProjectGraphInputSchema = z.object({
|
||||||
|
projectId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type ComputationGraphProcedureContext = Pick<TRPCContext, "db">;
|
||||||
|
|
||||||
|
export const computationGraphDetailProcedures = createComputationGraphDetailProcedures({
|
||||||
|
resourceGraphInputSchema: ResourceGraphInputSchema,
|
||||||
|
projectGraphInputSchema: ProjectGraphInputSchema,
|
||||||
|
readResourceGraphSnapshot,
|
||||||
|
readProjectGraphSnapshot,
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function getResourceGraphData(
|
||||||
|
ctx: ComputationGraphProcedureContext,
|
||||||
|
input: z.infer<typeof ResourceGraphInputSchema>,
|
||||||
|
) {
|
||||||
|
return readResourceGraphSnapshot(ctx, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getProjectGraphData(
|
||||||
|
ctx: ComputationGraphProcedureContext,
|
||||||
|
input: z.infer<typeof ProjectGraphInputSchema>,
|
||||||
|
) {
|
||||||
|
return readProjectGraphSnapshot(ctx, input);
|
||||||
|
}
|
||||||
@@ -1,27 +1,14 @@
|
|||||||
import { z } from "zod";
|
import { createTRPCRouter, controllerProcedure } from "../trpc.js";
|
||||||
import { createTRPCRouter, controllerProcedure, type TRPCContext } from "../trpc.js";
|
import {
|
||||||
import { createComputationGraphDetailProcedures } from "./computation-graph-detail.js";
|
computationGraphDetailProcedures,
|
||||||
import { readProjectGraphSnapshot } from "./computation-graph-project.js";
|
getProjectGraphData,
|
||||||
import { readResourceGraphSnapshot } from "./computation-graph-resource.js";
|
getResourceGraphData,
|
||||||
|
ProjectGraphInputSchema,
|
||||||
|
ResourceGraphInputSchema,
|
||||||
|
} from "./computation-graph-procedure-support.js";
|
||||||
import { type GraphLink, type GraphNode } from "./computation-graph-shared.js";
|
import { type GraphLink, type GraphNode } from "./computation-graph-shared.js";
|
||||||
export type { GraphLink, GraphNode } from "./computation-graph-shared.js";
|
export type { GraphLink, GraphNode } from "./computation-graph-shared.js";
|
||||||
|
|
||||||
const resourceGraphInputSchema = z.object({
|
|
||||||
resourceId: z.string(),
|
|
||||||
month: z.string().regex(/^\d{4}-\d{2}$/),
|
|
||||||
});
|
|
||||||
|
|
||||||
const projectGraphInputSchema = z.object({
|
|
||||||
projectId: z.string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const computationGraphDetailProcedures = createComputationGraphDetailProcedures({
|
|
||||||
resourceGraphInputSchema,
|
|
||||||
projectGraphInputSchema,
|
|
||||||
readResourceGraphSnapshot,
|
|
||||||
readProjectGraphSnapshot,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Router ─────────────────────────────────────────────────────────────────
|
// ─── Router ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export const computationGraphRouter = createTRPCRouter({
|
export const computationGraphRouter = createTRPCRouter({
|
||||||
@@ -31,13 +18,13 @@ export const computationGraphRouter = createTRPCRouter({
|
|||||||
* for a single resource in a single month.
|
* for a single resource in a single month.
|
||||||
*/
|
*/
|
||||||
getResourceData: controllerProcedure
|
getResourceData: controllerProcedure
|
||||||
.input(resourceGraphInputSchema)
|
.input(ResourceGraphInputSchema)
|
||||||
.query(({ ctx, input }) => readResourceGraphSnapshot(ctx, input)),
|
.query(({ ctx, input }) => getResourceGraphData(ctx, input)),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project View: Estimate, Commercial, Experience, Effort, Spread, Budget
|
* Project View: Estimate, Commercial, Experience, Effort, Spread, Budget
|
||||||
*/
|
*/
|
||||||
getProjectData: controllerProcedure
|
getProjectData: controllerProcedure
|
||||||
.input(projectGraphInputSchema)
|
.input(ProjectGraphInputSchema)
|
||||||
.query(({ ctx, input }) => readProjectGraphSnapshot(ctx, input)),
|
.query(({ ctx, input }) => getProjectGraphData(ctx, input)),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user