Fas 2 steg 5: Scan-to-scan-diff + konfliktlösning, samt buggfix depleted-transaktion i reconciliation

This commit is contained in:
Sven (AAMOS AI)
2026-08-07 01:30:31 +07:00
parent 218bc44d08
commit 4a4f448e1c
26 changed files with 10590 additions and 13 deletions
@@ -0,0 +1,69 @@
import { describe, expect, it } from "vitest";
import { diffScans } from "../src/scan-diff.js";
const PINNED = new Date("2026-08-07T00:00:00.000Z");
function item(overrides: Partial<Parameters<typeof diffScans>[0][number]> = {}) {
return {
id: "prev-1",
displayName: "Mjölk",
quantity: 1,
unit: "LITER",
storageLocationId: "loc-fridge",
...overrides,
};
}
function obs(overrides: Partial<Parameters<typeof diffScans>[1][number]> = {}) {
return {
displayName: "Mjölk",
quantity: 1,
unit: "LITER",
storageLocationId: "loc-fridge",
observationConfidence: 0.95,
...overrides,
};
}
describe("diffScans", () => {
it("marks identical items unchanged", () => {
const result = diffScans([item()], [obs()], PINNED);
expect(result.rows).toHaveLength(1);
expect(result.rows[0]?.kind).toBe("unchanged");
expect(result.pendingVanishedIds).toEqual([]);
});
it("detects new item", () => {
const result = diffScans([], [obs({ displayName: "Ost" })], PINNED);
expect(result.rows).toHaveLength(1);
expect(result.rows[0]?.kind).toBe("new_item");
});
it("detects vanished item as proposal only", () => {
const result = diffScans([item()], [], PINNED);
expect(result.rows).toHaveLength(1);
expect(result.rows[0]?.kind).toBe("vanished");
expect(result.pendingVanishedIds).toEqual(["prev-1"]);
});
it("detects quantity change", () => {
const result = diffScans([item()], [obs({ quantity: 0.5 })], PINNED);
expect(result.rows[0]?.kind).toBe("quantity_changed");
expect(result.rows[0]?.previousQuantity).toBe(1);
expect(result.rows[0]?.newQuantity).toBe(0.5);
});
it("detects moved item", () => {
const result = diffScans([item()], [obs({ storageLocationId: "loc-freezer" })], PINNED);
expect(result.rows[0]?.kind).toBe("moved");
});
it("sorts changes before unchanged", () => {
const result = diffScans(
[item({ id: "a", displayName: "A" }), item({ id: "b", displayName: "B" })],
[obs({ displayName: "A", quantity: 0.5 }), obs({ displayName: "B" })],
PINNED,
);
expect(result.rows.map((r) => r.kind)).toEqual(["quantity_changed", "unchanged"]);
});
});