Replace Revit CSV backend with Linear XLSX
This commit is contained in:
parent
52d3b1a270
commit
1cfeb06ec7
65 changed files with 4764 additions and 3717 deletions
|
|
@ -0,0 +1,79 @@
|
|||
import { eq } from "drizzle-orm";
|
||||
import {
|
||||
assertExternalModelConfigurationUpdateProjectCommand,
|
||||
createExternalModelConfigurationUpdateProjectCommand,
|
||||
type ExternalModelConfigurationSnapshot,
|
||||
} from "../../domain/models/external-model-configuration-project-command.model.js";
|
||||
import type {
|
||||
ExecuteExternalModelConfigurationCommandInput,
|
||||
ExternalModelConfigurationProjectCommandStore,
|
||||
} from "../../domain/ports/external-model-configuration-project-command.store.js";
|
||||
import type { AppDatabase } from "../database-context.js";
|
||||
import { externalModelConfigurations } from "../schema/external-model-configurations.js";
|
||||
import { projects } from "../schema/projects.js";
|
||||
import { executeProjectCommandTransaction } from "./project-command-transaction.persistence.js";
|
||||
|
||||
export class ExternalModelConfigurationProjectCommandRepository
|
||||
implements ExternalModelConfigurationProjectCommandStore {
|
||||
constructor(private readonly database: AppDatabase) {}
|
||||
|
||||
execute(input: ExecuteExternalModelConfigurationCommandInput) {
|
||||
assertExternalModelConfigurationUpdateProjectCommand(input.command);
|
||||
return executeProjectCommandTransaction(this.database, input, (tx) => {
|
||||
const project = tx.select({ id: projects.id }).from(projects)
|
||||
.where(eq(projects.id, input.projectId)).get();
|
||||
if (!project) throw new Error("Project not found.");
|
||||
const current = tx.select().from(externalModelConfigurations)
|
||||
.where(eq(externalModelConfigurations.projectId, input.projectId)).get() ?? null;
|
||||
assertSameSnapshot(current, input.command.payload.expected);
|
||||
const target = input.command.payload.target;
|
||||
if (target !== null && target.projectId !== input.projectId) {
|
||||
throw new Error("Die Revit-XLSX-Konfiguration gehört zu einem anderen Projekt.");
|
||||
}
|
||||
if (sameSnapshot(current, target)) {
|
||||
throw new Error("Die Revit-XLSX-Konfiguration wurde nicht geändert.");
|
||||
}
|
||||
if (target === null) {
|
||||
tx.delete(externalModelConfigurations)
|
||||
.where(eq(externalModelConfigurations.projectId, input.projectId)).run();
|
||||
} else if (current === null) {
|
||||
tx.insert(externalModelConfigurations).values(target).run();
|
||||
} else {
|
||||
const updated = tx.update(externalModelConfigurations)
|
||||
.set({ configuration: target.configuration })
|
||||
.where(eq(externalModelConfigurations.id, current.id)).run();
|
||||
if (updated.changes !== 1) {
|
||||
throw new Error("Die Revit-XLSX-Konfiguration wurde zwischenzeitlich geändert.");
|
||||
}
|
||||
}
|
||||
return createExternalModelConfigurationUpdateProjectCommand(target, current);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function assertSameSnapshot(
|
||||
current: ExternalModelConfigurationSnapshot | null,
|
||||
expected: ExternalModelConfigurationSnapshot | null
|
||||
) {
|
||||
if (!sameSnapshot(current, expected)) {
|
||||
throw new Error("Die Revit-XLSX-Konfiguration wurde zwischenzeitlich geändert.");
|
||||
}
|
||||
}
|
||||
|
||||
function sameSnapshot(
|
||||
left: ExternalModelConfigurationSnapshot | null,
|
||||
right: ExternalModelConfigurationSnapshot | null
|
||||
) {
|
||||
return canonicalJson(left) === canonicalJson(right);
|
||||
}
|
||||
|
||||
function canonicalJson(value: unknown): string {
|
||||
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
||||
if (value !== null && typeof value === "object") {
|
||||
const record = value as Record<string, unknown>;
|
||||
return `{${Object.keys(record).sort().map(
|
||||
(key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`
|
||||
).join(",")}}`;
|
||||
}
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue