Create clean release database baseline

This commit is contained in:
2026-07-31 14:07:26 +02:00
parent 5bee3cb103
commit 734a2bcfc4
129 changed files with 2121 additions and 30607 deletions
@@ -18,36 +18,7 @@ export const distributionBoardInsertCommandType =
"distribution-board.insert" as const;
export const distributionBoardDeleteCommandType =
"distribution-board.delete" as const;
export const legacyDistributionBoardStructureCommandSchemaVersion = 1 as const;
export const previousDistributionBoardStructureCommandSchemaVersion = 2 as const;
export const distributionBoardStructureCommandSchemaVersion = 3 as const;
const legacyDefaultCircuitSectionDefinitions = [
{
key: "lighting",
displayName: "Lighting",
prefix: "-1F",
sortOrder: 10,
},
{
key: "single_phase",
displayName: "Single-phase circuits",
prefix: "-2F",
sortOrder: 20,
},
{
key: "three_phase",
displayName: "Three-phase circuits",
prefix: "-3F",
sortOrder: 30,
},
{
key: "unassigned",
displayName: "Unassigned",
prefix: "-UF",
sortOrder: 90,
},
] as const;
export const distributionBoardStructureCommandSchemaVersion = 1 as const;
export const defaultCircuitSectionDefinitions = [
{
@@ -76,31 +47,6 @@ export const defaultCircuitSectionDefinitions = [
},
] as const;
interface LegacyDistributionBoardStructureSnapshot {
distributionBoard: {
id: string;
projectId: string;
name: string;
};
circuitList: DistributionBoardStructureSnapshot["circuitList"];
sections: LegacyCircuitSectionSnapshot[];
}
interface PreviousDistributionBoardStructureSnapshot {
distributionBoard: DistributionBoardStructureSnapshot["distributionBoard"];
circuitList: DistributionBoardStructureSnapshot["circuitList"];
sections: LegacyCircuitSectionSnapshot[];
}
interface LegacyCircuitSectionSnapshot {
id: string;
circuitListId: string;
key: string;
displayName: string;
prefix: string;
sortOrder: number;
}
export interface DistributionBoardStructureSnapshot {
distributionBoard: {
id: string;
@@ -140,22 +86,15 @@ export interface DistributionBoardStructureSnapshot {
export interface NormalizedDistributionBoardStructureSnapshot {
distributionBoard: DistributionBoardStructureSnapshot["distributionBoard"];
circuitList: DistributionBoardStructureSnapshot["circuitList"];
sections: Array<
LegacyCircuitSectionSnapshot & {
category: CircuitGroupCategory | null;
groupNumber: number | null;
}
>;
sections: DistributionBoardStructureSnapshot["sections"];
components: DistributionBoardStructureSnapshot["components"];
}
interface DistributionBoardStructureCommandPayload<
TStructure = DistributionBoardStructureSnapshot,
> {
structure: TStructure;
interface DistributionBoardStructureCommandPayload {
structure: DistributionBoardStructureSnapshot;
}
interface CurrentDistributionBoardStructureProjectCommand
interface DistributionBoardStructureProjectCommandBase
extends SerializedProjectCommand<DistributionBoardStructureCommandPayload> {
schemaVersion: typeof distributionBoardStructureCommandSchemaVersion;
type:
@@ -163,41 +102,19 @@ interface CurrentDistributionBoardStructureProjectCommand
| typeof distributionBoardDeleteCommandType;
}
interface LegacyDistributionBoardStructureProjectCommand
extends SerializedProjectCommand<
DistributionBoardStructureCommandPayload<LegacyDistributionBoardStructureSnapshot>
> {
schemaVersion: typeof legacyDistributionBoardStructureCommandSchemaVersion;
type:
| typeof distributionBoardInsertCommandType
| typeof distributionBoardDeleteCommandType;
}
interface PreviousDistributionBoardStructureProjectCommand
extends SerializedProjectCommand<
DistributionBoardStructureCommandPayload<PreviousDistributionBoardStructureSnapshot>
> {
schemaVersion: typeof previousDistributionBoardStructureCommandSchemaVersion;
type:
| typeof distributionBoardInsertCommandType
| typeof distributionBoardDeleteCommandType;
}
export interface DistributionBoardInsertProjectCommand
extends CurrentDistributionBoardStructureProjectCommand {
extends DistributionBoardStructureProjectCommandBase {
type: typeof distributionBoardInsertCommandType;
}
export interface DistributionBoardDeleteProjectCommand
extends CurrentDistributionBoardStructureProjectCommand {
extends DistributionBoardStructureProjectCommandBase {
type: typeof distributionBoardDeleteCommandType;
}
export type DistributionBoardStructureProjectCommand =
| DistributionBoardInsertProjectCommand
| DistributionBoardDeleteProjectCommand
| PreviousDistributionBoardStructureProjectCommand
| LegacyDistributionBoardStructureProjectCommand;
| DistributionBoardDeleteProjectCommand;
export function createDistributionBoardStructureSnapshot(
projectId: string,
@@ -296,35 +213,6 @@ export function assertDistributionBoardDeleteProjectCommand(
export function normalizeDistributionBoardStructureProjectCommand(
command: DistributionBoardStructureProjectCommand
): NormalizedDistributionBoardStructureSnapshot {
if (
command.schemaVersion ===
legacyDistributionBoardStructureCommandSchemaVersion
) {
return {
distributionBoard: {
...command.payload.structure.distributionBoard,
floorId: null,
supplyType: null,
},
circuitList: command.payload.structure.circuitList,
sections: command.payload.structure.sections.map(
normalizeLegacySection
),
components: [],
};
}
if (
command.schemaVersion ===
previousDistributionBoardStructureCommandSchemaVersion
) {
return {
...command.payload.structure,
sections: command.payload.structure.sections.map(
normalizeLegacySection
),
components: [],
};
}
return command.payload.structure;
}
@@ -340,26 +228,10 @@ export function invertDistributionBoardStructureProjectCommand(
} as DistributionBoardStructureProjectCommand;
}
function normalizeLegacySection(
section: LegacyCircuitSectionSnapshot
): NormalizedDistributionBoardStructureSnapshot["sections"][number] {
const category =
section.key === "lighting" ||
section.key === "single_phase" ||
section.key === "three_phase"
? section.key
: null;
return {
...section,
category,
groupNumber: category === null ? null : 1,
};
}
export function assertDistributionBoardStructureSnapshot(
structure: unknown
): asserts structure is DistributionBoardStructureSnapshot {
assertDistributionBoardStructureSnapshotVersion(structure, "current");
assertDistributionBoardStructureSnapshotVersion(structure);
}
function assertDistributionBoardStructureProjectCommand(
@@ -375,63 +247,36 @@ function assertDistributionBoardStructureProjectCommand(
) {
throw new Error("Unsupported distribution-board structure command.");
}
if (
command.schemaVersion ===
legacyDistributionBoardStructureCommandSchemaVersion
) {
assertDistributionBoardStructureSnapshotVersion(
command.payload.structure,
"legacy"
);
return;
}
if (
command.schemaVersion ===
previousDistributionBoardStructureCommandSchemaVersion
) {
assertDistributionBoardStructureSnapshotVersion(
command.payload.structure,
"previous"
);
return;
}
if (
command.schemaVersion !==
distributionBoardStructureCommandSchemaVersion
) {
throw new Error("Unsupported distribution-board structure command.");
}
assertDistributionBoardStructureSnapshotVersion(
command.payload.structure,
"current"
);
assertDistributionBoardStructureSnapshotVersion(command.payload.structure);
}
function assertDistributionBoardStructureSnapshotVersion(
structure: unknown,
version: "legacy" | "previous" | "current"
structure: unknown
) {
const current = version === "current";
if (
!isPlainObject(structure) ||
Object.keys(structure).length !== (current ? 4 : 3)
Object.keys(structure).length !== 4
) {
throw new Error("Distribution-board structure is invalid.");
}
const { distributionBoard, circuitList, sections, components } =
structure;
const expectedSections = current
? defaultCircuitSectionDefinitions
: legacyDefaultCircuitSectionDefinitions;
const expectedSections = defaultCircuitSectionDefinitions;
if (
!isPlainObject(distributionBoard) ||
Object.keys(distributionBoard).length !==
(version === "legacy" ? 3 : 5) ||
Object.keys(distributionBoard).length !== 5 ||
!isPlainObject(circuitList) ||
Object.keys(circuitList).length !== 4 ||
!Array.isArray(sections) ||
sections.length !== expectedSections.length ||
(current && (!Array.isArray(components) || components.length !== 2))
!Array.isArray(components) ||
components.length !== 2
) {
throw new Error("Distribution-board structure is incomplete.");
}
@@ -441,10 +286,8 @@ function assertDistributionBoardStructureSnapshotVersion(
`distributionBoard.${field}`
);
}
if (version !== "legacy") {
assertNullableId(distributionBoard.floorId, "distributionBoard.floorId");
assertNullableSupplyType(distributionBoard.supplyType);
}
assertNullableId(distributionBoard.floorId, "distributionBoard.floorId");
assertNullableSupplyType(distributionBoard.supplyType);
for (const [field, value] of Object.entries(circuitList)) {
assertNonEmptyString(value, `circuitList.${field}`);
}
@@ -462,7 +305,7 @@ function assertDistributionBoardStructureSnapshotVersion(
const expected = expectedSections[index];
if (
!isPlainObject(section) ||
Object.keys(section).length !== (current ? 8 : 6)
Object.keys(section).length !== 8
) {
throw new Error("Default circuit section is invalid.");
}
@@ -477,10 +320,8 @@ function assertDistributionBoardStructureSnapshotVersion(
section.displayName !== expected.displayName ||
section.prefix !== expected.prefix ||
section.sortOrder !== expected.sortOrder ||
(current &&
(!("category" in expected) ||
section.category !== expected.category ||
section.groupNumber !== expected.groupNumber))
section.category !== expected.category ||
section.groupNumber !== expected.groupNumber
) {
throw new Error(
"Distribution-board structure has invalid default sections."
@@ -488,9 +329,7 @@ function assertDistributionBoardStructureSnapshotVersion(
}
}
if (current) {
assertDefaultComponents(components, circuitList.id);
}
assertDefaultComponents(components, circuitList.id);
}
function assertDefaultComponents(