Add configurable distribution supply types
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
import { z } from "zod";
|
||||
import {
|
||||
defaultDistributionBoardSupplyTypes,
|
||||
distributionBoardSupplyTypes,
|
||||
} from "../../shared/constants/distribution-board.js";
|
||||
|
||||
export const legacyProjectStateSnapshotSchemaVersion = 1 as const;
|
||||
export const projectStateSnapshotSchemaVersion = 2 as const;
|
||||
export const previousProjectStateSnapshotSchemaVersion = 2 as const;
|
||||
export const distributionBoardProjectStateSnapshotSchemaVersion = 3 as const;
|
||||
export const projectStateSnapshotSchemaVersion = 4 as const;
|
||||
|
||||
const idSchema = z.string().trim().min(1);
|
||||
const nullableStringSchema = z.string().nullable();
|
||||
@@ -23,7 +29,14 @@ const projectSchema = legacyProjectSchema.extend({
|
||||
description: z.string().trim().min(1).max(2000).nullable(),
|
||||
});
|
||||
|
||||
const distributionBoardSchema = z
|
||||
const currentProjectSchema = projectSchema.extend({
|
||||
enabledDistributionBoardSupplyTypes: z
|
||||
.array(z.enum(distributionBoardSupplyTypes))
|
||||
.min(1)
|
||||
.refine((values) => new Set(values).size === values.length),
|
||||
});
|
||||
|
||||
const legacyDistributionBoardSchema = z
|
||||
.object({
|
||||
id: idSchema,
|
||||
projectId: idSchema,
|
||||
@@ -31,6 +44,13 @@ const distributionBoardSchema = z
|
||||
})
|
||||
.strict();
|
||||
|
||||
const distributionBoardSchema = legacyDistributionBoardSchema
|
||||
.extend({
|
||||
floorId: idSchema.nullable(),
|
||||
supplyType: z.enum(distributionBoardSupplyTypes).nullable(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const circuitListSchema = z
|
||||
.object({
|
||||
id: idSchema,
|
||||
@@ -140,8 +160,7 @@ const roomSchema = z
|
||||
})
|
||||
.strict();
|
||||
|
||||
const projectStateSnapshotContents = {
|
||||
distributionBoards: z.array(distributionBoardSchema),
|
||||
const commonProjectStateSnapshotContents = {
|
||||
circuitLists: z.array(circuitListSchema),
|
||||
circuitSections: z.array(circuitSectionSchema),
|
||||
circuits: z.array(circuitSchema),
|
||||
@@ -154,15 +173,37 @@ const legacyProjectStateSnapshotSchema = z
|
||||
.object({
|
||||
schemaVersion: z.literal(legacyProjectStateSnapshotSchemaVersion),
|
||||
project: legacyProjectSchema,
|
||||
...projectStateSnapshotContents,
|
||||
distributionBoards: z.array(legacyDistributionBoardSchema),
|
||||
...commonProjectStateSnapshotContents,
|
||||
})
|
||||
.strict();
|
||||
|
||||
const previousProjectStateSnapshotSchema = z
|
||||
.object({
|
||||
schemaVersion: z.literal(previousProjectStateSnapshotSchemaVersion),
|
||||
project: projectSchema,
|
||||
distributionBoards: z.array(legacyDistributionBoardSchema),
|
||||
...commonProjectStateSnapshotContents,
|
||||
})
|
||||
.strict();
|
||||
|
||||
const distributionBoardProjectStateSnapshotSchema = z
|
||||
.object({
|
||||
schemaVersion: z.literal(
|
||||
distributionBoardProjectStateSnapshotSchemaVersion
|
||||
),
|
||||
project: projectSchema,
|
||||
distributionBoards: z.array(distributionBoardSchema),
|
||||
...commonProjectStateSnapshotContents,
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const projectStateSnapshotSchema = z
|
||||
.object({
|
||||
schemaVersion: z.literal(projectStateSnapshotSchemaVersion),
|
||||
project: projectSchema,
|
||||
...projectStateSnapshotContents,
|
||||
project: currentProjectSchema,
|
||||
distributionBoards: z.array(distributionBoardSchema),
|
||||
...commonProjectStateSnapshotContents,
|
||||
})
|
||||
.strict();
|
||||
|
||||
@@ -176,20 +217,34 @@ export function parseProjectStateSnapshot(
|
||||
const version = isPlainObject(value) ? value.schemaVersion : undefined;
|
||||
const snapshot =
|
||||
version === legacyProjectStateSnapshotSchemaVersion
|
||||
? upgradeLegacyProjectStateSnapshot(
|
||||
legacyProjectStateSnapshotSchema.parse(value)
|
||||
? upgradeDistributionBoardProjectStateSnapshot(
|
||||
upgradePreviousProjectStateSnapshot(
|
||||
upgradeLegacyProjectStateSnapshot(
|
||||
legacyProjectStateSnapshotSchema.parse(value)
|
||||
)
|
||||
)
|
||||
)
|
||||
: projectStateSnapshotSchema.parse(value);
|
||||
: version === previousProjectStateSnapshotSchemaVersion
|
||||
? upgradeDistributionBoardProjectStateSnapshot(
|
||||
upgradePreviousProjectStateSnapshot(
|
||||
previousProjectStateSnapshotSchema.parse(value)
|
||||
)
|
||||
)
|
||||
: version === distributionBoardProjectStateSnapshotSchemaVersion
|
||||
? upgradeDistributionBoardProjectStateSnapshot(
|
||||
distributionBoardProjectStateSnapshotSchema.parse(value)
|
||||
)
|
||||
: projectStateSnapshotSchema.parse(value);
|
||||
assertProjectStateSnapshotRelations(snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function upgradeLegacyProjectStateSnapshot(
|
||||
snapshot: z.infer<typeof legacyProjectStateSnapshotSchema>
|
||||
): ProjectStateSnapshot {
|
||||
): z.infer<typeof previousProjectStateSnapshotSchema> {
|
||||
return {
|
||||
...snapshot,
|
||||
schemaVersion: projectStateSnapshotSchemaVersion,
|
||||
schemaVersion: previousProjectStateSnapshotSchemaVersion,
|
||||
project: {
|
||||
...snapshot.project,
|
||||
internalProjectNumber: null,
|
||||
@@ -200,6 +255,35 @@ function upgradeLegacyProjectStateSnapshot(
|
||||
};
|
||||
}
|
||||
|
||||
function upgradePreviousProjectStateSnapshot(
|
||||
snapshot: z.infer<typeof previousProjectStateSnapshotSchema>
|
||||
): z.infer<typeof distributionBoardProjectStateSnapshotSchema> {
|
||||
return {
|
||||
...snapshot,
|
||||
schemaVersion: distributionBoardProjectStateSnapshotSchemaVersion,
|
||||
distributionBoards: snapshot.distributionBoards.map((board) => ({
|
||||
...board,
|
||||
floorId: null,
|
||||
supplyType: null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
function upgradeDistributionBoardProjectStateSnapshot(
|
||||
snapshot: z.infer<typeof distributionBoardProjectStateSnapshotSchema>
|
||||
): ProjectStateSnapshot {
|
||||
return {
|
||||
...snapshot,
|
||||
schemaVersion: projectStateSnapshotSchemaVersion,
|
||||
project: {
|
||||
...snapshot.project,
|
||||
enabledDistributionBoardSupplyTypes: [
|
||||
...defaultDistributionBoardSupplyTypes,
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
||||
return value !== null && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
@@ -245,6 +329,23 @@ function assertProjectStateSnapshotRelations(
|
||||
|
||||
for (const board of snapshot.distributionBoards) {
|
||||
assertProjectOwnership(board.projectId, projectId, "distribution board");
|
||||
if (board.floorId !== null) {
|
||||
assertReference(
|
||||
floorIds,
|
||||
board.floorId,
|
||||
"distribution board floor"
|
||||
);
|
||||
}
|
||||
if (
|
||||
board.supplyType !== null &&
|
||||
!snapshot.project.enabledDistributionBoardSupplyTypes.includes(
|
||||
board.supplyType
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
"Snapshot distribution board uses a disabled supply type."
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const list of snapshot.circuitLists) {
|
||||
assertProjectOwnership(list.projectId, projectId, "circuit list");
|
||||
|
||||
Reference in New Issue
Block a user