diff --git a/lambda/blf-sync/blf-sync-handler.ts b/lambda/blf-sync/blf-sync-handler.ts
index d03a66e..39818eb 100644
--- a/lambda/blf-sync/blf-sync-handler.ts
+++ b/lambda/blf-sync/blf-sync-handler.ts
@@ -185,5 +185,8 @@ export async function handler(event: BlfSyncEvent = {}) {
failed,
};
console.log(JSON.stringify(summary));
+ if (failed > 0) {
+ throw new Error(`blf sync patch failed for ${failed} user(s)`);
+ }
return summary;
}
diff --git a/lambda/blf-sync/blf-sync.test.ts b/lambda/blf-sync/blf-sync.test.ts
index f564a0c..11764bb 100644
--- a/lambda/blf-sync/blf-sync.test.ts
+++ b/lambda/blf-sync/blf-sync.test.ts
@@ -135,6 +135,34 @@ test("merge is a no-op when XML already matches", () => {
assert.equal(blfsEqual(first.xml, second.xml), true);
});
+test("merge keeps assigned shared-parking IDs so later runs are a no-op", () => {
+ const first = mergeDepartmentBlfs({
+ currentXml: "",
+ selfExtension: "116",
+ colleagues,
+ contract: SLOT_CONTRACT["t54w-door-unlock-with-sp"],
+ });
+ const assigned = serializeBlfs(
+ parseBlfs(first.xml).map((entry) =>
+ entry.blfType === "SharedParking" || entry.blfType === "Line"
+ ? { ...entry, id: String(900 + entry.blfNo) }
+ : entry
+ )
+ );
+ const second = mergeDepartmentBlfs({
+ currentXml: assigned,
+ selfExtension: "116",
+ colleagues,
+ contract: SLOT_CONTRACT["t54w-door-unlock-with-sp"],
+ });
+ assert.equal(second.changed, false);
+ const parking = parseBlfs(second.xml).filter((e) => e.blfNo >= 3 && e.blfNo <= 5);
+ assert.deepEqual(
+ parking.map((e) => e.id),
+ ["903", "904", "905"]
+ );
+});
+
test("serializeBlfs normalizes empty lists", () => {
assert.equal(serializeBlfs([]), "");
assert.equal(blfsEqual("", serializeBlfs([])), true);
diff --git a/lambda/blf-sync/merge.ts b/lambda/blf-sync/merge.ts
index d8d1036..a2d2ee8 100644
--- a/lambda/blf-sync/merge.ts
+++ b/lambda/blf-sync/merge.ts
@@ -68,13 +68,21 @@ export function mergeDepartmentBlfs(input: {
value: "",
};
- const parking: BlfEntry[] = input.contract.sharedParking.map((slot) => ({
- id: "-1",
- blfNo: slot.blfNo,
- blfType: "SharedParking",
- blfTypeId: "3",
- value: slot.value,
- }));
+ const parking: BlfEntry[] = input.contract.sharedParking.map((slot) => {
+ const existing = current.find(
+ (entry) =>
+ entry.blfNo === slot.blfNo &&
+ entry.blfType === "SharedParking" &&
+ entry.value === slot.value
+ );
+ return {
+ id: existing?.id ?? "-1",
+ blfNo: slot.blfNo,
+ blfType: "SharedParking",
+ blfTypeId: existing?.blfTypeId ?? "3",
+ value: slot.value,
+ };
+ });
const managed: BlfEntry[] = placedColleagues.map((colleague, index) => ({
id: String(colleague.id),