Add optional room areas

This commit is contained in:
Julian Appel 2026-09-27 20:00:03 +02:00
parent a6500e2b26
commit dce31ee143
26 changed files with 3669 additions and 78 deletions

View file

@ -35,7 +35,8 @@ import {
type ExternalModelStateSnapshot,
} from "../../external-model/domain/external-model-contracts.js";
export const projectStateSnapshotSchemaVersion = 7 as const;
export const projectStateSnapshotSchemaVersion = 8 as const;
const buildingProjectStateSnapshotSchemaVersion = 7 as const;
const coverProjectStateSnapshotSchemaVersion = 6 as const;
const boardInfoProjectStateSnapshotSchemaVersion = 5 as const;
const previousProjectStateSnapshotSchemaVersion = 4 as const;
@ -260,7 +261,7 @@ const floorSchema = legacyFloorSchema
.extend({ buildingId: idSchema.nullable() })
.strict();
const roomSchema = z
const legacyRoomSchema = z
.object({
id: idSchema,
projectId: idSchema,
@ -270,6 +271,10 @@ const roomSchema = z
})
.strict();
const roomSchema = legacyRoomSchema
.extend({ areaM2: finiteNumberSchema.nonnegative().nullable() })
.strict();
const distributionBoardComponentSchema = z
.object({
id: idSchema,
@ -504,14 +509,27 @@ export function parseExternalModelStateSnapshot(
return externalModelStateSchema.parse(value);
}
// Versions 1-6 have floors without a building and no building list.
// Versions 1-6 have floors without a building and no building list. Versions
// 1-7 have rooms without an area.
const previousProjectStateSnapshotContents = {
circuitLists: z.array(circuitListSchema),
circuitSections: z.array(circuitSectionSchema),
circuits: z.array(circuitSchema),
projectDevices: z.array(projectDeviceSchema),
floors: z.array(legacyFloorSchema),
rooms: z.array(roomSchema),
rooms: z.array(legacyRoomSchema),
distributionBoardComponents: z.array(distributionBoardComponentSchema),
circuitProtectionDevices: z.array(circuitProtectionDeviceSchema),
distributionBoardComponentProtectionDevices: z.array(
componentProtectionDeviceSchema
),
};
const buildingProjectStateSnapshotContents = {
...previousProjectStateSnapshotContents,
buildings: z.array(buildingSchema),
floors: z.array(floorSchema),
rooms: z.array(legacyRoomSchema),
distributionBoardComponents: z.array(distributionBoardComponentSchema),
circuitProtectionDevices: z.array(circuitProtectionDeviceSchema),
distributionBoardComponentProtectionDevices: z.array(
@ -520,15 +538,8 @@ const previousProjectStateSnapshotContents = {
};
const projectStateSnapshotContents = {
...previousProjectStateSnapshotContents,
buildings: z.array(buildingSchema),
floors: z.array(floorSchema),
...buildingProjectStateSnapshotContents,
rooms: z.array(roomSchema),
distributionBoardComponents: z.array(distributionBoardComponentSchema),
circuitProtectionDevices: z.array(circuitProtectionDeviceSchema),
distributionBoardComponentProtectionDevices: z.array(
componentProtectionDeviceSchema
),
};
export const projectStateSnapshotSchema = z
@ -542,6 +553,17 @@ export const projectStateSnapshotSchema = z
})
.strict();
const buildingProjectStateSnapshotSchema = z
.object({
schemaVersion: z.literal(buildingProjectStateSnapshotSchemaVersion),
project: projectSchema,
distributionBoards: z.array(distributionBoardSchema),
externalCsvConfiguration: externalCsvConfigurationSnapshotSchema.nullable(),
externalModel: externalModelStateSchema,
...buildingProjectStateSnapshotContents,
})
.strict();
const coverProjectStateSnapshotSchema = z
.object({
schemaVersion: z.literal(coverProjectStateSnapshotSchemaVersion),
@ -634,6 +656,20 @@ export function parseProjectStateSnapshot(
function upgradePreviousProjectStateSnapshot(value: unknown): unknown {
const cover = upgradeToCoverProjectStateSnapshot(value);
if (
cover !== null &&
typeof cover === "object" &&
!Array.isArray(cover) &&
(cover as { schemaVersion?: unknown }).schemaVersion ===
buildingProjectStateSnapshotSchemaVersion
) {
const previous = buildingProjectStateSnapshotSchema.parse(cover);
return {
...previous,
schemaVersion: projectStateSnapshotSchemaVersion,
rooms: previous.rooms.map((room) => ({ ...room, areaM2: null })),
};
}
if (
cover === null ||
typeof cover !== "object" ||
@ -644,14 +680,15 @@ function upgradePreviousProjectStateSnapshot(value: unknown): unknown {
return cover;
}
// Every supported version before 7 lacks buildings; its floors had no
// building.
// building. Build version 7 first so the room-area upgrade above remains a
// single exact transition.
const previous = coverProjectStateSnapshotSchema.parse(cover);
return {
return upgradePreviousProjectStateSnapshot({
...previous,
schemaVersion: projectStateSnapshotSchemaVersion,
schemaVersion: buildingProjectStateSnapshotSchemaVersion,
buildings: [],
floors: previous.floors.map((floor) => ({ ...floor, buildingId: null })),
};
});
}
function upgradeToCoverProjectStateSnapshot(value: unknown): unknown {