feat(plan): resolveCell/resolveGrid return arrays; dashboard shows up to 3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-08 10:53:26 +02:00
parent 80dc8a5c69
commit 72888bf9cd
9 changed files with 320 additions and 256 deletions

View File

@@ -89,10 +89,9 @@ afterAll(async () => {
// ---------------------------------------------------------------------------
describe("plan.service.resolveCell", () => {
it("returns null when nothing covers the date", async () => {
// No entry, no override for (adminUserId, "2099-01-01")
it("returns [] when nothing covers the date", async () => {
const result = await resolveCell(adminUserId, "2099-01-01");
expect(result).toBeNull();
expect(result).toEqual([]);
});
it("returns the entry that covers the date", async () => {
@@ -107,17 +106,14 @@ describe("plan.service.resolveCell", () => {
},
});
const result = await resolveCell(adminUserId, "2099-06-05");
expect(result).not.toBeNull();
expect(result?.source).toBe("entry");
expect(result?.note).toBe(`${N}PLC upgrade`);
expect(result?.category).toBe("work");
expect(result?.rangeFrom).toBe("2099-06-01");
expect(result?.rangeTo).toBe("2099-06-10");
expect(result.length).toBe(1);
expect(result[0].source).toBe("entry");
expect(result[0].note).toBe(`${N}PLC upgrade`);
expect(result[0].rangeFrom).toBe("2099-06-01");
expect(result[0].rangeTo).toBe("2099-06-10");
});
it("returns the override for that day, not the entry", async () => {
// An entry covers 2099-06-01..2099-06-10, but an override on 2099-06-05
// takes precedence.
it("returns overrides (entries hidden) when an override exists", async () => {
await prisma.work_plan_entries.create({
data: {
user_id: adminUserId,
@@ -138,10 +134,51 @@ describe("plan.service.resolveCell", () => {
},
});
const result = await resolveCell(adminUserId, "2099-06-05");
expect(result).not.toBeNull();
expect(result?.source).toBe("override");
expect(result?.note).toBe(`${N}Volno po noční`);
expect(result?.category).toBe("leave");
expect(result.length).toBe(1);
expect(result[0].source).toBe("override");
expect(result[0].note).toBe(`${N}Volno po noční`);
});
it("returns multiple additive entries newest-first", async () => {
await prisma.work_plan_entries.create({
data: {
user_id: adminUserId,
date_from: new Date("2099-06-01"),
date_to: new Date("2099-06-10"),
category: "work",
note: `${N}first`,
created_by: adminUserId,
},
});
await prisma.work_plan_entries.create({
data: {
user_id: adminUserId,
date_from: new Date("2099-06-05"),
date_to: new Date("2099-06-05"),
category: "work",
note: `${N}second`,
created_by: adminUserId,
},
});
const result = await resolveCell(adminUserId, "2099-06-05");
expect(result.length).toBe(2);
expect(result[0].note).toBe(`${N}second`); // newest first
});
it("caps the returned records at MAX_RECORDS_PER_CELL", async () => {
for (let i = 0; i < 4; i++) {
await prisma.work_plan_overrides.create({
data: {
user_id: adminUserId,
shift_date: new Date("2099-06-06"),
category: "leave",
note: `${N}cap${i}`,
created_by: adminUserId,
},
});
}
const result = await resolveCell(adminUserId, "2099-06-06");
expect(result.length).toBe(3);
});
it("ignores soft-deleted entries and overrides", async () => {
@@ -157,7 +194,7 @@ describe("plan.service.resolveCell", () => {
},
});
const result = await resolveCell(adminUserId, "2099-06-05");
expect(result).toBeNull();
expect(result).toEqual([]);
});
});
@@ -178,11 +215,11 @@ describe("plan.service.resolveGrid", () => {
},
});
const cells = await resolveGrid([adminUserId], "2099-06-01", "2099-06-05");
expect(cells[adminUserId]["2099-06-01"]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-02"]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-03"]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-04"]).toBeNull();
expect(cells[adminUserId]["2099-06-05"]).toBeNull();
expect(cells[adminUserId]["2099-06-01"][0]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-02"][0]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-03"][0]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-04"]).toEqual([]);
expect(cells[adminUserId]["2099-06-05"]).toEqual([]);
});
it("applies override on a covered day", async () => {
@@ -206,9 +243,9 @@ describe("plan.service.resolveGrid", () => {
},
});
const cells = await resolveGrid([adminUserId], "2099-06-01", "2099-06-03");
expect(cells[adminUserId]["2099-06-01"]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-02"]?.note).toBe(`${N}B`);
expect(cells[adminUserId]["2099-06-03"]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-01"][0]?.note).toBe(`${N}A`);
expect(cells[adminUserId]["2099-06-02"][0]?.note).toBe(`${N}B`);
expect(cells[adminUserId]["2099-06-03"][0]?.note).toBe(`${N}A`);
});
});
@@ -857,7 +894,7 @@ describe("HTTP /api/admin/plan", () => {
const body = res.json();
expect(body.data.users).toBeDefined();
expect(body.data.cells[adminUserId]).toBeDefined();
expect(body.data.cells[adminUserId]["2097-06-01"].note).toBe(
expect(body.data.cells[adminUserId]["2097-06-01"][0].note).toBe(
`${N}grid test`,
);
});