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

@ -22,6 +22,11 @@ import {
createProjectRoomInsertProjectCommand,
createProjectRoomSnapshot,
createProjectRoomUpdateProjectCommand,
projectRoomCommandSchemaVersion,
projectRoomDeleteCommandType,
projectRoomUpdateCommandType,
type LegacyProjectRoomDeleteProjectCommand,
type LegacyProjectRoomUpdateProjectCommand,
} from "../src/domain/models/project-location-structure-project-command.model.js";
import {
createFloor,
@ -66,10 +71,12 @@ describe("project-location structure project command", () => {
floorId: floor.id,
roomNumber: " 001 ",
roomName: " Technik ",
areaM2: 23.456,
});
assert.equal(floor.name, "EG");
assert.equal(room.roomNumber, "001");
assert.equal(room.roomName, "Technik");
assert.equal(room.areaM2, 23.456);
assert.throws(
() =>
createProjectFloorInsertProjectCommand({
@ -113,6 +120,7 @@ describe("project-location structure project command", () => {
floorId: "floor-1",
roomNumber: "001",
roomName: "Technik",
areaM2: 23.456,
},
8
);
@ -120,7 +128,7 @@ describe("project-location structure project command", () => {
await updateRoom(
"project-1",
"room-1",
{ roomNumber: "101", roomName: "Büro" },
{ roomNumber: "101", roomName: "Büro", areaM2: null },
10
);
await deleteFloor("project-1", "floor-1", 11);
@ -141,6 +149,7 @@ describe("project-location structure project command", () => {
floorId: "floor-1",
roomNumber: "001",
roomName: "Technik",
areaM2: 23.456,
expectedRevision: 8,
},
},
@ -155,6 +164,7 @@ describe("project-location structure project command", () => {
body: {
roomNumber: "101",
roomName: "Büro",
areaM2: null,
floorId: null,
expectedRevision: 10,
},
@ -199,6 +209,7 @@ describe("project-location structure project command", () => {
floorId: null,
roomNumber: "002",
roomName: "Lager",
areaM2: 48.125,
};
const roomCommand = createProjectRoomUpdateProjectCommand(room, updatedRoom);
const roomResult = repository.execute({
@ -427,6 +438,64 @@ describe("project-location structure project command", () => {
}
});
it("upgrades version-1 room commands without overwriting a newer area", () => {
const context = createTestDatabase();
try {
const repository = new ProjectLocationStructureProjectCommandRepository(context.db);
const history = new ProjectHistoryRepository(context.db);
const room = createProjectRoomSnapshot("project-1", {
roomNumber: "001",
roomName: "Technik",
});
context.db.insert(rooms).values(room).run();
const { areaM2: _expectedArea, ...legacyExpected } = room;
const legacyTarget = { ...legacyExpected, roomName: "Technik alt" };
const legacyUpdate: LegacyProjectRoomUpdateProjectCommand = {
schemaVersion: 1,
type: projectRoomUpdateCommandType,
payload: { expected: legacyExpected, target: legacyTarget },
};
const updated = repository.execute({
projectId: "project-1",
expectedRevision: 0,
source: "user",
command: legacyUpdate,
});
assert.equal(updated.inverse.schemaVersion, projectRoomCommandSchemaVersion);
assert.equal(context.db.select().from(rooms).get()?.areaM2, null);
const undo = history.getNextCommand("project-1", "undo");
assert.ok(undo);
repository.execute({
projectId: "project-1",
expectedRevision: 1,
source: "undo",
historyTargetChangeSetId: undo.changeSetId,
command: updated.inverse,
});
context.db.update(rooms).set({ areaM2: 12.5 }).where(eq(rooms.id, room.id)).run();
const legacyDelete: LegacyProjectRoomDeleteProjectCommand = {
schemaVersion: 1,
type: projectRoomDeleteCommandType,
payload: { room: legacyExpected },
};
assert.throws(
() =>
repository.execute({
projectId: "project-1",
expectedRevision: 2,
source: "user",
command: legacyDelete,
}),
/changed before deletion/
);
assert.equal(context.db.select().from(rooms).get()?.areaM2, 12.5);
} finally {
context.close();
}
});
it("rejects foreign, stale and changed locations without partial writes", () => {
const context = createTestDatabase();
try {