Persist populated group deletion

This commit is contained in:
2026-07-30 20:10:10 +02:00
parent db4c757018
commit 99bdf6491b
15 changed files with 754 additions and 5 deletions
@@ -0,0 +1,88 @@
import {
assertCircuitGroupSubtreeSnapshot,
type CircuitGroupSubtreeSnapshot,
} from "./circuit-group-subtree-snapshot.model.js";
import type { SerializedProjectCommand } from "./project-command.model.js";
export const circuitGroupDeleteSubtreeCommandType =
"circuit-group.delete-subtree" as const;
export const circuitGroupRestoreSubtreeCommandType =
"circuit-group.restore-subtree" as const;
export const circuitGroupSubtreeCommandSchemaVersion = 1 as const;
interface Payload {
snapshot: CircuitGroupSubtreeSnapshot;
}
export interface CircuitGroupDeleteSubtreeProjectCommand
extends SerializedProjectCommand<Payload> {
schemaVersion: typeof circuitGroupSubtreeCommandSchemaVersion;
type: typeof circuitGroupDeleteSubtreeCommandType;
}
export interface CircuitGroupRestoreSubtreeProjectCommand
extends SerializedProjectCommand<Payload> {
schemaVersion: typeof circuitGroupSubtreeCommandSchemaVersion;
type: typeof circuitGroupRestoreSubtreeCommandType;
}
export type CircuitGroupSubtreeProjectCommand =
| CircuitGroupDeleteSubtreeProjectCommand
| CircuitGroupRestoreSubtreeProjectCommand;
export function createCircuitGroupDeleteSubtreeProjectCommand(
snapshot: CircuitGroupSubtreeSnapshot
): CircuitGroupDeleteSubtreeProjectCommand {
const command: CircuitGroupDeleteSubtreeProjectCommand = {
schemaVersion: circuitGroupSubtreeCommandSchemaVersion,
type: circuitGroupDeleteSubtreeCommandType,
payload: { snapshot },
};
assertCircuitGroupDeleteSubtreeProjectCommand(command);
return command;
}
export function createCircuitGroupRestoreSubtreeProjectCommand(
snapshot: CircuitGroupSubtreeSnapshot
): CircuitGroupRestoreSubtreeProjectCommand {
const command: CircuitGroupRestoreSubtreeProjectCommand = {
schemaVersion: circuitGroupSubtreeCommandSchemaVersion,
type: circuitGroupRestoreSubtreeCommandType,
payload: { snapshot },
};
assertCircuitGroupRestoreSubtreeProjectCommand(command);
return command;
}
export function assertCircuitGroupDeleteSubtreeProjectCommand(
command: SerializedProjectCommand<unknown>
): asserts command is CircuitGroupDeleteSubtreeProjectCommand {
assertCommand(command, circuitGroupDeleteSubtreeCommandType);
}
export function assertCircuitGroupRestoreSubtreeProjectCommand(
command: SerializedProjectCommand<unknown>
): asserts command is CircuitGroupRestoreSubtreeProjectCommand {
assertCommand(command, circuitGroupRestoreSubtreeCommandType);
}
function assertCommand(
command: SerializedProjectCommand<unknown>,
type:
| typeof circuitGroupDeleteSubtreeCommandType
| typeof circuitGroupRestoreSubtreeCommandType
) {
if (
command.schemaVersion !== circuitGroupSubtreeCommandSchemaVersion ||
command.type !== type ||
!isPlainObject(command.payload) ||
Object.keys(command.payload).length !== 1
) {
throw new Error("Unsupported circuit-group subtree command.");
}
assertCircuitGroupSubtreeSnapshot(command.payload.snapshot);
}
function isPlainObject(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
@@ -0,0 +1,24 @@
import type { CircuitGroupSubtreeSnapshot } from "../models/circuit-group-subtree-snapshot.model.js";
import type { CircuitGroupSubtreeProjectCommand } from "../models/circuit-group-subtree-project-command.model.js";
import type {
AppendedProjectRevision,
ProjectRevisionSource,
} from "./project-revision.store.js";
export interface ExecuteCircuitGroupSubtreeCommandInput {
projectId: string;
expectedRevision: number;
source: ProjectRevisionSource;
description?: string;
actorId?: string;
historyTargetChangeSetId?: string;
command: CircuitGroupSubtreeProjectCommand;
}
export interface CircuitGroupSubtreeProjectCommandStore {
capture(projectId: string, groupId: string): CircuitGroupSubtreeSnapshot;
execute(input: ExecuteCircuitGroupSubtreeCommandInput): {
revision: AppendedProjectRevision;
inverse: CircuitGroupSubtreeProjectCommand;
};
}
@@ -101,6 +101,7 @@ import type { CircuitStructureProjectCommandStore } from "../ports/circuit-struc
import type { CircuitGroupStructureProjectCommandStore } from "../ports/circuit-group-structure-project-command.store.js";
import type { CircuitGroupRenumberProjectCommandStore } from "../ports/circuit-group-renumber-project-command.store.js";
import type { CircuitGroupMoveProjectCommandStore } from "../ports/circuit-group-move-project-command.store.js";
import type { CircuitGroupSubtreeProjectCommandStore } from "../ports/circuit-group-subtree-project-command.store.js";
import type { DistributionBoardStructureProjectCommandStore } from "../ports/distribution-board-structure-project-command.store.js";
import type { DistributionBoardComponentStructureProjectCommandStore } from "../ports/distribution-board-component-structure-project-command.store.js";
import type {
@@ -131,6 +132,12 @@ import {
assertCircuitGroupMoveProjectCommand,
circuitGroupMoveCommandType,
} from "../models/circuit-group-move-project-command.model.js";
import {
assertCircuitGroupDeleteSubtreeProjectCommand,
assertCircuitGroupRestoreSubtreeProjectCommand,
circuitGroupDeleteSubtreeCommandType,
circuitGroupRestoreSubtreeCommandType,
} from "../models/circuit-group-subtree-project-command.model.js";
import type { ProjectLocationStructureProjectCommandStore } from "../ports/project-location-structure-project-command.store.js";
import type { ProjectDeviceProjectCommandStore } from "../ports/project-device-project-command.store.js";
import type { ProjectDeviceRowSyncProjectCommandStore } from "../ports/project-device-row-sync-project-command.store.js";
@@ -169,6 +176,7 @@ export class ProjectCommandService implements ProjectCommandExecutor {
private readonly circuitGroupStructureStore: CircuitGroupStructureProjectCommandStore,
private readonly circuitGroupRenumberStore: CircuitGroupRenumberProjectCommandStore,
private readonly circuitGroupMoveStore: CircuitGroupMoveProjectCommandStore,
private readonly circuitGroupSubtreeStore: CircuitGroupSubtreeProjectCommandStore,
private readonly historyStore: ProjectHistoryStore
) {}
@@ -399,6 +407,20 @@ export class ProjectCommandService implements ProjectCommandExecutor {
command: input.command,
}).revision;
}
case circuitGroupDeleteSubtreeCommandType: {
assertCircuitGroupDeleteSubtreeProjectCommand(input.command);
return this.circuitGroupSubtreeStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupRestoreSubtreeCommandType: {
assertCircuitGroupRestoreSubtreeProjectCommand(input.command);
return this.circuitGroupSubtreeStore.execute({
...input,
command: input.command,
}).revision;
}
case projectFloorInsertCommandType: {
assertProjectFloorInsertProjectCommand(input.command);
return this.projectLocationStructureStore.execute({