forked from jappel/leistungsbilanz-ts
Add per-project socket limit and Revit socket device-type flag
- Project setting maxSocketsPerCircuit (migration 0018, project.update-settings schema 4, snapshot schema 11); older command and snapshot versions keep or upgrade the value to null. - Revit configuration schema 2 marks device types as socket; version 1 stays readable and derives the flag from socketCount family rules. - Settings dialog field and device-type card on the Revit page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
85cbdbf8e0
commit
e48042bde3
35 changed files with 3781 additions and 41 deletions
|
|
@ -5,7 +5,12 @@ import {
|
|||
type ExternalXlsxTransportConfiguration,
|
||||
} from "../xlsx/external-xlsx-contracts.js";
|
||||
|
||||
export const externalModelConfigurationSchemaVersion = 1 as const;
|
||||
// Version 2 adds `deviceTypes[].isSocket`. Version 1 stays readable wherever
|
||||
// it is stored (configuration row, import-batch copies, history commands,
|
||||
// snapshots); socket classification then derives from the family rules
|
||||
// (`resolveSocketDeviceTypeIds`).
|
||||
export const externalModelConfigurationSchemaVersion = 2 as const;
|
||||
export const legacyExternalModelConfigurationSchemaVersion = 1 as const;
|
||||
export const externalQuantityRules = ["one", "socketCount"] as const;
|
||||
export type ExternalQuantityRule = (typeof externalQuantityRules)[number];
|
||||
|
||||
|
|
@ -21,6 +26,8 @@ export interface ExternalDeviceTypeConfiguration {
|
|||
name: string;
|
||||
category: CircuitGroupCategory;
|
||||
defaults: ExternalDeviceTypeDefaults;
|
||||
// Required from schema version 2, absent in version 1.
|
||||
isSocket?: boolean;
|
||||
}
|
||||
|
||||
export interface ExternalFamilyTypeRule {
|
||||
|
|
@ -32,7 +39,9 @@ export interface ExternalFamilyTypeRule {
|
|||
|
||||
export interface ExternalModelConfiguration
|
||||
extends ExternalXlsxTransportConfiguration {
|
||||
schemaVersion: typeof externalModelConfigurationSchemaVersion;
|
||||
schemaVersion:
|
||||
| typeof externalModelConfigurationSchemaVersion
|
||||
| typeof legacyExternalModelConfigurationSchemaVersion;
|
||||
deviceTypes: ExternalDeviceTypeConfiguration[];
|
||||
familyTypeRules: ExternalFamilyTypeRule[];
|
||||
}
|
||||
|
|
@ -49,7 +58,11 @@ export function createDefaultExternalModelConfiguration(): ExternalModelConfigur
|
|||
export function assertExternalModelConfiguration(
|
||||
value: unknown
|
||||
): asserts value is ExternalModelConfiguration {
|
||||
if (!isRecord(value) || value.schemaVersion !== externalModelConfigurationSchemaVersion) {
|
||||
if (
|
||||
!isRecord(value) ||
|
||||
(value.schemaVersion !== externalModelConfigurationSchemaVersion &&
|
||||
value.schemaVersion !== legacyExternalModelConfigurationSchemaVersion)
|
||||
) {
|
||||
throw new Error("Nicht unterstützte Revit-XLSX-Konfiguration.");
|
||||
}
|
||||
assertExactKeys(value, [
|
||||
|
|
@ -72,7 +85,11 @@ export function assertExternalModelConfiguration(
|
|||
const deviceTypeIds = new Set<string>();
|
||||
const deviceTypeNames = new Set<string>();
|
||||
for (const [index, deviceType] of value.deviceTypes.entries()) {
|
||||
assertDeviceType(deviceType, index);
|
||||
assertDeviceType(
|
||||
deviceType,
|
||||
index,
|
||||
value.schemaVersion === externalModelConfigurationSchemaVersion
|
||||
);
|
||||
assertUnique(deviceTypeIds, deviceType.id, "Geräteart-ID");
|
||||
assertUnique(deviceTypeNames, deviceType.name, "Geräteartname");
|
||||
}
|
||||
|
|
@ -153,9 +170,22 @@ function assertColumns(
|
|||
}
|
||||
}
|
||||
|
||||
function assertDeviceType(value: unknown, index: number): asserts value is ExternalDeviceTypeConfiguration {
|
||||
function assertDeviceType(
|
||||
value: unknown,
|
||||
index: number,
|
||||
hasSocketFlag: boolean
|
||||
): asserts value is ExternalDeviceTypeConfiguration {
|
||||
if (!isRecord(value)) throw new Error(`Geräteart ${index + 1} ist ungültig.`);
|
||||
assertExactKeys(value, ["id", "name", "category", "defaults"], `Geräteart ${index + 1}`);
|
||||
assertExactKeys(
|
||||
value,
|
||||
hasSocketFlag
|
||||
? ["id", "name", "category", "defaults", "isSocket"]
|
||||
: ["id", "name", "category", "defaults"],
|
||||
`Geräteart ${index + 1}`
|
||||
);
|
||||
if (hasSocketFlag && typeof value.isSocket !== "boolean") {
|
||||
throw new Error(`Geräteart ${index + 1}.isSocket muss ja oder nein sein.`);
|
||||
}
|
||||
assertUuid(value.id, `Geräteart ${index + 1}.id`);
|
||||
assertNonEmptyString(value.name, `Geräteart ${index + 1}.name`);
|
||||
if (!(["lighting", "single_phase", "three_phase"] as unknown[]).includes(value.category)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue