Add configurable distribution supply types
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
distributionBoardSupplyTypes,
|
||||
type DistributionBoardSupplyType,
|
||||
} from "../../shared/constants/distribution-board.js";
|
||||
import type { SerializedProjectCommand } from "./project-command.model.js";
|
||||
|
||||
export const distributionBoardUpdateCommandType =
|
||||
"distribution-board.update" as const;
|
||||
export const distributionBoardUpdateCommandSchemaVersion = 1 as const;
|
||||
|
||||
export interface DistributionBoardUpdateValues {
|
||||
floorId: string | null;
|
||||
supplyType: DistributionBoardSupplyType | null;
|
||||
}
|
||||
|
||||
export type DistributionBoardUpdateField =
|
||||
keyof DistributionBoardUpdateValues;
|
||||
export type DistributionBoardUpdatePatch =
|
||||
Partial<DistributionBoardUpdateValues>;
|
||||
|
||||
export interface DistributionBoardUpdateFieldChange<
|
||||
TField extends DistributionBoardUpdateField =
|
||||
DistributionBoardUpdateField,
|
||||
> {
|
||||
field: TField;
|
||||
value: DistributionBoardUpdateValues[TField];
|
||||
}
|
||||
|
||||
export interface DistributionBoardUpdateCommandPayload {
|
||||
distributionBoardId: string;
|
||||
changes: DistributionBoardUpdateFieldChange[];
|
||||
}
|
||||
|
||||
export interface DistributionBoardUpdateProjectCommand
|
||||
extends SerializedProjectCommand<DistributionBoardUpdateCommandPayload> {
|
||||
schemaVersion: typeof distributionBoardUpdateCommandSchemaVersion;
|
||||
type: typeof distributionBoardUpdateCommandType;
|
||||
}
|
||||
|
||||
export function createDistributionBoardUpdateProjectCommand(
|
||||
distributionBoardId: string,
|
||||
patch: DistributionBoardUpdatePatch
|
||||
): DistributionBoardUpdateProjectCommand {
|
||||
const command: DistributionBoardUpdateProjectCommand = {
|
||||
schemaVersion: distributionBoardUpdateCommandSchemaVersion,
|
||||
type: distributionBoardUpdateCommandType,
|
||||
payload: {
|
||||
distributionBoardId,
|
||||
changes: Object.entries(patch).map(([field, value]) => ({
|
||||
field: field as DistributionBoardUpdateField,
|
||||
value,
|
||||
})) as DistributionBoardUpdateFieldChange[],
|
||||
},
|
||||
};
|
||||
assertDistributionBoardUpdateProjectCommand(command);
|
||||
return command;
|
||||
}
|
||||
|
||||
export function assertDistributionBoardUpdateProjectCommand(
|
||||
command: SerializedProjectCommand<unknown>
|
||||
): asserts command is DistributionBoardUpdateProjectCommand {
|
||||
if (
|
||||
command.schemaVersion !== distributionBoardUpdateCommandSchemaVersion ||
|
||||
command.type !== distributionBoardUpdateCommandType ||
|
||||
!isPlainObject(command.payload)
|
||||
) {
|
||||
throw new Error("Unsupported distribution-board update command.");
|
||||
}
|
||||
const { distributionBoardId, changes } = command.payload;
|
||||
if (
|
||||
typeof distributionBoardId !== "string" ||
|
||||
!distributionBoardId.trim() ||
|
||||
!Array.isArray(changes) ||
|
||||
changes.length === 0
|
||||
) {
|
||||
throw new Error(
|
||||
"Distribution-board update command requires an id and changes."
|
||||
);
|
||||
}
|
||||
const seen = new Set<string>();
|
||||
for (const change of changes) {
|
||||
if (
|
||||
!isPlainObject(change) ||
|
||||
(change.field !== "floorId" && change.field !== "supplyType") ||
|
||||
seen.has(change.field)
|
||||
) {
|
||||
throw new Error(
|
||||
"Distribution-board update contains an invalid or duplicate field."
|
||||
);
|
||||
}
|
||||
if (change.field === "floorId") {
|
||||
if (
|
||||
change.value !== null &&
|
||||
(typeof change.value !== "string" || !change.value.trim())
|
||||
) {
|
||||
throw new Error("floorId must be a non-empty string or null.");
|
||||
}
|
||||
} else if (
|
||||
change.value !== null &&
|
||||
!distributionBoardSupplyTypes.includes(
|
||||
change.value as DistributionBoardSupplyType
|
||||
)
|
||||
) {
|
||||
throw new Error("supplyType is invalid.");
|
||||
}
|
||||
seen.add(change.field);
|
||||
}
|
||||
}
|
||||
|
||||
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
||||
return value !== null && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
Reference in New Issue
Block a user