Replace Revit CSV backend with Linear XLSX

This commit is contained in:
Julian Appel 2026-09-30 08:46:07 +02:00
parent 52d3b1a270
commit 1cfeb06ec7
65 changed files with 4764 additions and 3717 deletions

View file

@ -8,11 +8,16 @@ import {
} from "../src/domain/models/project-state-snapshot.model.js";
import { remapProjectState } from "../src/domain/models/project-transfer.model.js";
import { createNamedProjectSnapshotSchema } from "../src/shared/validation/project-snapshot.schemas.js";
import { createDefaultExternalCsvConfiguration } from "../src/external-model/csv/external-csv-contracts.js";
import { externalCsvTestColumns } from "./fixtures/revit-csv-fixtures.js";
/** Removes the fields introduced by snapshot schema version 9. */
function withoutVersionNineFields<
T extends { distributionBoards: object[] },
>(snapshot: T): T {
const record = snapshot as Record<string, unknown>;
record.externalCsvConfiguration = null;
delete record.externalModelConfiguration;
for (const board of snapshot.distributionBoards) {
delete (board as Record<string, unknown>).feedingDistributionBoardId;
delete (board as Record<string, unknown>).feedingCircuitId;
@ -77,7 +82,7 @@ function minimalSnapshot() {
projectEditor: null as string | null,
},
distributionBoards: [],
externalCsvConfiguration: null,
externalModelConfiguration: null,
externalModel: {
source: null,
importBatches: [],
@ -315,6 +320,7 @@ describe("project state snapshot model", () => {
const baseline = withoutVersionSixFields(structuredClone(minimalSnapshot()));
baseline.schemaVersion = 1 as typeof baseline.schemaVersion;
delete (baseline.project as Record<string, unknown>).isPublicBuilding;
delete (baseline as Record<string, unknown>).externalModelConfiguration;
delete (baseline as Record<string, unknown>).externalCsvConfiguration;
delete (baseline as Record<string, unknown>).externalModel;
@ -322,7 +328,7 @@ describe("project state snapshot model", () => {
assert.equal(upgraded.schemaVersion, projectStateSnapshotSchemaVersion);
assert.equal(upgraded.project.isPublicBuilding, false);
assert.equal(upgraded.externalCsvConfiguration, null);
assert.equal(upgraded.externalModelConfiguration, null);
});
it("upgrades snapshot version 2 with an empty external CSV configuration", () => {
@ -334,7 +340,7 @@ describe("project state snapshot model", () => {
const upgraded = parseProjectStateSnapshot(previous);
assert.equal(upgraded.schemaVersion, projectStateSnapshotSchemaVersion);
assert.equal(upgraded.externalCsvConfiguration, null);
assert.equal(upgraded.externalModelConfiguration, null);
assert.deepEqual(upgraded.externalModel, {
source: null,
importBatches: [],
@ -351,7 +357,7 @@ describe("project state snapshot model", () => {
const upgraded = parseProjectStateSnapshot(previous);
assert.equal(upgraded.schemaVersion, projectStateSnapshotSchemaVersion);
assert.equal(upgraded.externalCsvConfiguration, null);
assert.equal(upgraded.externalModelConfiguration, null);
assert.deepEqual(upgraded.externalModel, {
source: null,
importBatches: [],
@ -360,6 +366,28 @@ describe("project state snapshot model", () => {
});
});
it("rejects legacy CSV configuration and imported state with a German migration error", () => {
const configured = withoutVersionNineFields(structuredClone(minimalSnapshot()));
configured.schemaVersion = 9 as typeof configured.schemaVersion;
configured.externalCsvConfiguration = {
id: "legacy",
projectId: "project-1",
configurationVersion: 1,
configuration: createDefaultExternalCsvConfiguration(externalCsvTestColumns),
};
assert.throws(() => parseProjectStateSnapshot(configured), /Revit-CSV-Daten/);
const imported = withoutVersionNineFields(structuredClone(minimalSnapshot()));
imported.schemaVersion = 9 as typeof imported.schemaVersion;
imported.externalModel.source = {
id: "legacy-source",
projectId: "project-1",
name: "Legacy",
sourceType: "revit_csv",
};
assert.throws(() => parseProjectStateSnapshot(imported), /Revit-CSV-Daten/);
});
it("upgrades snapshot version 5 with empty board info and cover fields", () => {
const previous = withoutVersionSixFields(protectedSnapshot());
previous.schemaVersion = 5 as typeof previous.schemaVersion;
@ -567,7 +595,7 @@ describe("project state snapshot model", () => {
});
assert.equal(parseProjectStateSnapshot(current).rooms[0]?.areaM2, 23.456);
const previous = structuredClone(current);
const previous = withoutVersionNineFields(structuredClone(current));
previous.schemaVersion = 7 as typeof previous.schemaVersion;
delete (previous.rooms[0] as Partial<(typeof previous.rooms)[number]>).areaM2;
const upgraded = parseProjectStateSnapshot(previous);