Add public building project setting

This commit is contained in:
2026-07-31 17:41:30 +02:00
parent 43a3bb0b69
commit 44b6fde940
29 changed files with 2057 additions and 54 deletions
@@ -6,7 +6,8 @@ import {
export const projectSettingsUpdateCommandType =
"project.update-settings" as const;
export const projectSettingsUpdateCommandSchemaVersion = 1 as const;
export const projectSettingsUpdateCommandSchemaVersion = 2 as const;
const previousProjectSettingsUpdateCommandSchemaVersion = 1 as const;
export interface ProjectSettingsValues {
name: string;
@@ -14,21 +15,37 @@ export interface ProjectSettingsValues {
externalProjectNumber: string | null;
buildingOwner: string | null;
description: string | null;
isPublicBuilding: boolean;
singlePhaseVoltageV: number;
threePhaseVoltageV: number;
enabledDistributionBoardSupplyTypes: DistributionBoardSupplyType[];
}
export interface ProjectSettingsUpdateProjectCommand
type PreviousProjectSettingsValues = Omit<
ProjectSettingsValues,
"isPublicBuilding"
>;
export interface CurrentProjectSettingsUpdateProjectCommand
extends SerializedProjectCommand<ProjectSettingsValues> {
schemaVersion: typeof projectSettingsUpdateCommandSchemaVersion;
type: typeof projectSettingsUpdateCommandType;
}
interface PreviousProjectSettingsUpdateProjectCommand
extends SerializedProjectCommand<PreviousProjectSettingsValues> {
schemaVersion: typeof previousProjectSettingsUpdateCommandSchemaVersion;
type: typeof projectSettingsUpdateCommandType;
}
export type ProjectSettingsUpdateProjectCommand =
| CurrentProjectSettingsUpdateProjectCommand
| PreviousProjectSettingsUpdateProjectCommand;
export function createProjectSettingsUpdateProjectCommand(
values: ProjectSettingsValues
): ProjectSettingsUpdateProjectCommand {
const command: ProjectSettingsUpdateProjectCommand = {
): CurrentProjectSettingsUpdateProjectCommand {
const command: CurrentProjectSettingsUpdateProjectCommand = {
schemaVersion: projectSettingsUpdateCommandSchemaVersion,
type: projectSettingsUpdateCommandType,
payload: { ...values },
@@ -42,7 +59,8 @@ export function assertProjectSettingsUpdateProjectCommand(
): asserts command is ProjectSettingsUpdateProjectCommand {
if (
command.type !== projectSettingsUpdateCommandType ||
command.schemaVersion !== projectSettingsUpdateCommandSchemaVersion
(command.schemaVersion !== projectSettingsUpdateCommandSchemaVersion &&
command.schemaVersion !== previousProjectSettingsUpdateCommandSchemaVersion)
) {
throw new Error("Unsupported project settings update command.");
}
@@ -58,8 +76,7 @@ export function assertProjectSettingsUpdateProjectCommand(
!isNullableTrimmedString(command.payload.buildingOwner, 200) ||
!isNullableTrimmedString(command.payload.description, 2000) ||
!isPositiveFiniteNumber(command.payload.singlePhaseVoltageV) ||
!isPositiveFiniteNumber(command.payload.threePhaseVoltageV) ||
Object.keys(command.payload).length !== 8
!isPositiveFiniteNumber(command.payload.threePhaseVoltageV)
) {
throw new Error(
"Project settings update command contains invalid values."
@@ -74,6 +91,18 @@ export function assertProjectSettingsUpdateProjectCommand(
"Project settings update command contains invalid supply types."
);
}
const isPreviousSchema =
command.schemaVersion === previousProjectSettingsUpdateCommandSchemaVersion;
if (
(isPreviousSchema && Object.keys(command.payload).length !== 8) ||
(!isPreviousSchema &&
(typeof command.payload.isPublicBuilding !== "boolean" ||
Object.keys(command.payload).length !== 9))
) {
throw new Error(
"Project settings update command contains invalid values."
);
}
}
function isValidSupplyTypes(
@@ -19,13 +19,14 @@ import {
resolveProjectVoltage,
} from "../services/project-voltage.service.js";
export const projectStateSnapshotSchemaVersion = 1 as const;
export const projectStateSnapshotSchemaVersion = 2 as const;
const previousProjectStateSnapshotSchemaVersion = 1 as const;
const idSchema = z.string().trim().min(1);
const nullableStringSchema = z.string().nullable();
const finiteNumberSchema = z.number().finite();
const projectSchema = z
const previousProjectSchema = z
.object({
id: idSchema,
name: z.string().trim().min(1),
@@ -42,6 +43,10 @@ const projectSchema = z
})
.strict();
const projectSchema = previousProjectSchema
.extend({ isPublicBuilding: z.boolean() })
.strict();
const distributionBoardSchema = z
.object({
id: idSchema,
@@ -267,6 +272,15 @@ export const projectStateSnapshotSchema = z
})
.strict();
const previousProjectStateSnapshotSchema = z
.object({
schemaVersion: z.literal(previousProjectStateSnapshotSchemaVersion),
project: previousProjectSchema,
distributionBoards: z.array(distributionBoardSchema),
...projectStateSnapshotContents,
})
.strict();
export type ProjectStateSnapshot = z.infer<
typeof projectStateSnapshotSchema
>;
@@ -274,12 +288,35 @@ export type ProjectStateSnapshot = z.infer<
export function parseProjectStateSnapshot(
value: unknown
): ProjectStateSnapshot {
const parsedSnapshot = projectStateSnapshotSchema.parse(value);
const parsedSnapshot = projectStateSnapshotSchema.parse(
upgradePreviousProjectStateSnapshot(value)
);
const snapshot = normalizeSnapshotPhaseTypes(parsedSnapshot);
assertProjectStateSnapshotRelations(snapshot);
return snapshot;
}
function upgradePreviousProjectStateSnapshot(value: unknown): unknown {
if (
value === null ||
typeof value !== "object" ||
Array.isArray(value) ||
(value as { schemaVersion?: unknown }).schemaVersion !==
previousProjectStateSnapshotSchemaVersion
) {
return value;
}
const previous = previousProjectStateSnapshotSchema.parse(value);
return {
...previous,
schemaVersion: projectStateSnapshotSchemaVersion,
project: {
...previous.project,
isPublicBuilding: false,
},
};
}
function normalizeSnapshotPhaseTypes(
snapshot: ProjectStateSnapshot
): ProjectStateSnapshot {