leistungsbilanz-ts/src/domain/models/distribution-board-subtree-project-command.model.ts

86 lines
3.2 KiB
TypeScript

import type { SerializedProjectCommand } from "./project-command.model.js";
import {
assertDistributionBoardSubtreeSnapshot,
type DistributionBoardSubtreeSnapshot,
} from "./distribution-board-subtree-snapshot.model.js";
export const distributionBoardInsertSubtreeCommandType =
"distribution-board.insert-subtree" as const;
export const distributionBoardDeleteSubtreeCommandType =
"distribution-board.delete-subtree" as const;
export const distributionBoardSubtreeCommandSchemaVersion = 1 as const;
interface Payload {
snapshot: DistributionBoardSubtreeSnapshot;
}
export interface DistributionBoardInsertSubtreeProjectCommand
extends SerializedProjectCommand<Payload> {
schemaVersion: typeof distributionBoardSubtreeCommandSchemaVersion;
type: typeof distributionBoardInsertSubtreeCommandType;
}
export interface DistributionBoardDeleteSubtreeProjectCommand
extends SerializedProjectCommand<Payload> {
schemaVersion: typeof distributionBoardSubtreeCommandSchemaVersion;
type: typeof distributionBoardDeleteSubtreeCommandType;
}
export type DistributionBoardSubtreeProjectCommand =
| DistributionBoardInsertSubtreeProjectCommand
| DistributionBoardDeleteSubtreeProjectCommand;
export function createDistributionBoardInsertSubtreeProjectCommand(
snapshot: DistributionBoardSubtreeSnapshot
): DistributionBoardInsertSubtreeProjectCommand {
const command: DistributionBoardInsertSubtreeProjectCommand = {
schemaVersion: distributionBoardSubtreeCommandSchemaVersion,
type: distributionBoardInsertSubtreeCommandType,
payload: { snapshot },
};
assertDistributionBoardInsertSubtreeProjectCommand(command);
return command;
}
export function createDistributionBoardDeleteSubtreeProjectCommand(
snapshot: DistributionBoardSubtreeSnapshot
): DistributionBoardDeleteSubtreeProjectCommand {
const command: DistributionBoardDeleteSubtreeProjectCommand = {
schemaVersion: distributionBoardSubtreeCommandSchemaVersion,
type: distributionBoardDeleteSubtreeCommandType,
payload: { snapshot },
};
assertDistributionBoardDeleteSubtreeProjectCommand(command);
return command;
}
export function assertDistributionBoardInsertSubtreeProjectCommand(
command: SerializedProjectCommand<unknown>
): asserts command is DistributionBoardInsertSubtreeProjectCommand {
assertCommand(command, distributionBoardInsertSubtreeCommandType);
}
export function assertDistributionBoardDeleteSubtreeProjectCommand(
command: SerializedProjectCommand<unknown>
): asserts command is DistributionBoardDeleteSubtreeProjectCommand {
assertCommand(command, distributionBoardDeleteSubtreeCommandType);
}
function assertCommand(
command: SerializedProjectCommand<unknown>,
type: DistributionBoardSubtreeProjectCommand["type"]
) {
if (
command.schemaVersion !== distributionBoardSubtreeCommandSchemaVersion ||
command.type !== type ||
!isPlainObject(command.payload) ||
Object.keys(command.payload).length !== 1
) {
throw new Error("Unsupported distribution-board subtree command.");
}
assertDistributionBoardSubtreeSnapshot(command.payload.snapshot);
}
function isPlainObject(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value);
}