Expose distribution board copy and delete API

This commit is contained in:
Julian Appel 2026-07-31 11:59:31 +02:00
parent 0fd564a930
commit 86f1d42e60
7 changed files with 182 additions and 2 deletions

View file

@ -5,10 +5,20 @@ import {
createDistributionBoardStructureSnapshot,
} from "../../domain/models/distribution-board-structure-project-command.model.js";
import {
createDistributionBoardDeleteSubtreeProjectCommand,
createDistributionBoardInsertSubtreeProjectCommand,
} from "../../domain/models/distribution-board-subtree-project-command.model.js";
import { cloneDistributionBoardSubtree } from "../../domain/models/distribution-board-subtree-snapshot.model.js";
import {
copyDistributionBoardSchema,
createDistributionBoardSchema,
deleteDistributionBoardSchema,
updateDistributionBoardSchema,
} from "../../shared/validation/project-structure.schemas.js";
import { projectCommandService } from "../composition/project-command-stores.js";
import {
distributionBoardSubtreeProjectCommandStore,
projectCommandService,
} from "../composition/project-command-stores.js";
import { distributionBoardRepository } from "../composition/application-repositories.js";
import { respondWithProjectCommandError } from "./project-command.controller.js";
@ -101,3 +111,85 @@ export async function updateDistributionBoard(
return respondWithProjectCommandError(error, res);
}
}
export async function copyDistributionBoard(
req: Request,
res: Response
) {
const ids = getDistributionBoardIds(req, res);
if (!ids) {
return;
}
const parsed = copyDistributionBoardSchema.safeParse(req.body);
if (!parsed.success) {
return res.status(400).json({ error: parsed.error.flatten() });
}
try {
const source = distributionBoardSubtreeProjectCommandStore.capture(
ids.projectId,
ids.distributionBoardId
);
const copy = cloneDistributionBoardSubtree(source, parsed.data.name);
const result = projectCommandService.executeUser({
projectId: ids.projectId,
expectedRevision: parsed.data.expectedRevision,
description: "Verteilung kopieren",
command:
createDistributionBoardInsertSubtreeProjectCommand(copy),
});
return res.status(201).json({
...result,
distributionBoard: copy.distributionBoard,
});
} catch (error) {
return respondWithProjectCommandError(error, res);
}
}
export async function deleteDistributionBoard(
req: Request,
res: Response
) {
const ids = getDistributionBoardIds(req, res);
if (!ids) {
return;
}
const parsed = deleteDistributionBoardSchema.safeParse(req.body);
if (!parsed.success) {
return res.status(400).json({ error: parsed.error.flatten() });
}
try {
const snapshot =
distributionBoardSubtreeProjectCommandStore.capture(
ids.projectId,
ids.distributionBoardId
);
const result = projectCommandService.executeUser({
projectId: ids.projectId,
expectedRevision: parsed.data.expectedRevision,
description: "Verteilung löschen",
command:
createDistributionBoardDeleteSubtreeProjectCommand(snapshot),
});
return res.json({
...result,
distributionBoardId: ids.distributionBoardId,
});
} catch (error) {
return respondWithProjectCommandError(error, res);
}
}
function getDistributionBoardIds(req: Request, res: Response) {
const { projectId, distributionBoardId } = req.params;
if (
typeof projectId !== "string" ||
typeof distributionBoardId !== "string" ||
!projectId.trim() ||
!distributionBoardId.trim()
) {
res.status(400).json({ error: "Invalid distribution board id" });
return null;
}
return { projectId, distributionBoardId };
}