Add serializable project commands

This commit is contained in:
2026-07-23 21:23:31 +02:00
parent 903d977443
commit b79faed320
9 changed files with 206 additions and 39 deletions
+74
View File
@@ -0,0 +1,74 @@
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
deserializeProjectCommand,
serializeProjectCommand,
type SerializedProjectCommand,
} from "../src/domain/models/project-command.model.js";
describe("serialized project commands", () => {
it("round-trips a versioned command envelope", () => {
const command: SerializedProjectCommand = {
schemaVersion: 1,
type: "circuit.update",
payload: {
circuitId: "circuit-1",
changes: {
displayName: "Werkstatt",
protectionRatedCurrent: 16,
isReserve: false,
remark: null,
},
},
};
assert.deepEqual(
deserializeProjectCommand(serializeProjectCommand(command)),
command
);
});
it("rejects values that JSON would lose or silently change", () => {
const invalidPayloads: unknown[] = [
{ value: undefined },
{ value: Number.NaN },
{ value: Number.POSITIVE_INFINITY },
{ value: new Date() },
];
for (const payload of invalidPayloads) {
assert.throws(() =>
serializeProjectCommand({
schemaVersion: 1,
type: "test.invalid",
payload: payload as never,
})
);
}
});
it("rejects cyclic payloads before persistence", () => {
const payload: Record<string, unknown> = {};
payload.self = payload;
assert.throws(
() =>
serializeProjectCommand({
schemaVersion: 1,
type: "test.cyclic",
payload: payload as never,
}),
/must not contain cycles/
);
});
it("rejects malformed serialized envelopes", () => {
assert.throws(
() =>
deserializeProjectCommand(
JSON.stringify({ schemaVersion: 0, type: "", payload: null })
),
/schema version/
);
});
});
+16 -7
View File
@@ -32,16 +32,17 @@ function appendTestRevision(
projectId: "project-1",
expectedRevision,
source: "user",
commandType: "circuit.update",
description: "Stromkreis bearbeiten",
actorId: "test-user",
forward: {
schemaVersion: 1,
data: { circuitId: "circuit-1", displayName: "Neu" },
type: "circuit.update",
payload: { circuitId: "circuit-1", displayName: "Neu" },
},
inverse: {
schemaVersion: 1,
data: { circuitId: "circuit-1", displayName: "Alt" },
type: "circuit.update",
payload: { circuitId: "circuit-1", displayName: "Alt" },
},
});
}
@@ -85,12 +86,20 @@ describe("project revision repository", () => {
commandType: "circuit.update",
payloadSchemaVersion: 1,
forwardPayloadJson: JSON.stringify({
circuitId: "circuit-1",
displayName: "Neu",
schemaVersion: 1,
type: "circuit.update",
payload: {
circuitId: "circuit-1",
displayName: "Neu",
},
}),
inversePayloadJson: JSON.stringify({
circuitId: "circuit-1",
displayName: "Alt",
schemaVersion: 1,
type: "circuit.update",
payload: {
circuitId: "circuit-1",
displayName: "Alt",
},
}),
});