feat(platform): checkpoint current implementation state

This commit is contained in:
2026-04-01 07:42:03 +02:00
parent 3e53471f05
commit 8c5be51251
125 changed files with 10269 additions and 17808 deletions
@@ -72,6 +72,21 @@ function createManagerCaller(db: Record<string, unknown>) {
});
}
function createAdminCaller(db: Record<string, unknown>) {
return createCaller({
session: {
user: { email: "admin@example.com", name: "Admin", image: null },
expires: "2099-01-01T00:00:00.000Z",
},
db: db as never,
dbUser: {
id: "user_admin",
systemRole: SystemRole.ADMIN,
permissionOverrides: null,
},
});
}
// ── Sample data ──────────────────────────────────────────────────────────────
function sampleNotification(overrides: Record<string, unknown> = {}) {
@@ -281,6 +296,45 @@ describe("notification.create", () => {
);
});
it("defaults task-like managed notifications to OPEN when no taskStatus is provided", async () => {
const created = sampleNotification({
userId: "target_user",
category: "TASK",
taskStatus: "OPEN",
});
const db = withUserLookup(
{
notification: {
create: vi.fn().mockResolvedValue(created),
findUnique: vi.fn().mockResolvedValue(created),
},
},
"user_mgr",
);
const caller = createManagerCaller(db);
const result = await caller.create({
userId: "target_user",
type: "TASK_CREATED",
title: "Review proposal",
category: "TASK",
});
expect(db.notification.create).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.objectContaining({
category: "TASK",
taskStatus: "OPEN",
}),
}),
);
expect(result).toMatchObject({
id: "notif_1",
category: "TASK",
taskStatus: "OPEN",
});
});
it("rejects creation by a regular user (FORBIDDEN)", async () => {
const db = withUserLookup({
notification: {
@@ -293,6 +347,36 @@ describe("notification.create", () => {
caller.create({ userId: "target", type: "INFO", title: "Nope" }),
).rejects.toThrow();
});
it("maps missing notification recipients to a not found error", async () => {
const db = withUserLookup(
{
notification: {
create: vi.fn().mockRejectedValue({
code: "P2003",
message: "Foreign key constraint failed",
meta: { field_name: "Notification_userId_fkey" },
}),
findUnique: vi.fn(),
},
},
"user_mgr",
);
const caller = createManagerCaller(db);
await expect(caller.create({
userId: "user_missing",
type: "INFO",
title: "Test notification",
})).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Notification recipient user not found",
});
expect(db.notification.findUnique).not.toHaveBeenCalled();
expect(emitNotificationCreated).not.toHaveBeenCalled();
});
});
// ─── createBroadcast ────────────────────────────────────────────────────────
@@ -590,6 +674,75 @@ describe("notification.createBroadcast", () => {
expect(emitTaskAssigned).not.toHaveBeenCalled();
});
it("maps missing broadcast recipients during fan-out to not found errors", async () => {
resolveRecipientsMock.mockResolvedValue(["user_a", "user_missing"]);
const txCreateBroadcast = vi.fn().mockResolvedValue({
id: "broadcast_tx_missing_recipient",
title: "Ops update",
createdAt: new Date("2026-03-30T10:00:00Z"),
});
const txUpdateBroadcast = vi.fn();
const txCreateNotification = vi.fn()
.mockResolvedValueOnce({ id: "notif_a", userId: "user_a" })
.mockRejectedValueOnce(
Object.assign(new Error("Foreign key constraint failed"), {
code: "P2003",
meta: { field_name: "Notification_userId_fkey" },
}),
);
const tx = {
notificationBroadcast: {
create: txCreateBroadcast,
update: txUpdateBroadcast,
},
notification: {
create: txCreateNotification,
},
};
const outerCreateBroadcast = vi.fn();
const outerUpdateBroadcast = vi.fn();
const outerCreateNotification = vi.fn();
const db = {
$transaction: vi.fn(async (callback: (db: typeof tx) => Promise<unknown>) => callback(tx)),
user: {
findUnique: vi.fn(),
},
notificationBroadcast: {
create: outerCreateBroadcast,
update: outerUpdateBroadcast,
},
notification: {
create: outerCreateNotification,
},
};
const caller = createManagerCaller(db);
await expect(caller.createBroadcast({
title: "Ops update",
body: "Email everyone",
channel: "both",
targetType: "all",
})).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Broadcast recipient user not found",
});
await Promise.resolve();
expect(txCreateBroadcast).toHaveBeenCalledTimes(1);
expect(txCreateNotification).toHaveBeenCalledTimes(2);
expect(txUpdateBroadcast).not.toHaveBeenCalled();
expect(outerCreateBroadcast).not.toHaveBeenCalled();
expect(outerUpdateBroadcast).not.toHaveBeenCalled();
expect(outerCreateNotification).not.toHaveBeenCalled();
expect(db.user.findUnique).not.toHaveBeenCalled();
expect(sendEmailMock).not.toHaveBeenCalled();
expect(emitNotificationCreated).not.toHaveBeenCalled();
expect(emitTaskAssigned).not.toHaveBeenCalled();
});
it("emits recipient SSE only after an immediate broadcast commits", async () => {
resolveRecipientsMock.mockResolvedValue(["user_a", "user_b"]);
@@ -1301,6 +1454,78 @@ describe("notification.updateTaskStatus", () => {
});
describe("notification.assignTask", () => {
it("returns NOT_FOUND when assigning a missing task", async () => {
const update = vi.fn();
const db = {
notification: {
findUnique: vi.fn().mockResolvedValue(null),
update,
},
};
const caller = createManagerCaller(db);
await expect(caller.assignTask({ id: "task_missing", assigneeId: "user_4" })).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Task not found",
});
expect(update).not.toHaveBeenCalled();
expect(emitTaskAssigned).not.toHaveBeenCalled();
});
it("maps missing task recipients to a not found error without side effects", async () => {
const db = {
notification: {
create: vi.fn().mockRejectedValue({
code: "P2003",
message: "Foreign key constraint failed",
meta: { field_name: "Notification_userId_fkey" },
}),
findUnique: vi.fn(),
},
};
const caller = createManagerCaller(db);
await expect(caller.createTask({
userId: "user_missing",
title: "Review proposal",
channel: "in_app",
})).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Task recipient user not found",
});
expect(db.notification.findUnique).not.toHaveBeenCalled();
expect(emitNotificationCreated).not.toHaveBeenCalled();
expect(emitTaskAssigned).not.toHaveBeenCalled();
});
it("rejects assigning non-task notifications", async () => {
const update = vi.fn();
const db = {
notification: {
findUnique: vi.fn().mockResolvedValue({
id: "notif_9",
category: "REMINDER",
assigneeId: null,
}),
update,
},
};
const caller = createManagerCaller(db);
await expect(caller.assignTask({ id: "notif_9", assigneeId: "user_4" })).rejects.toMatchObject({
code: "BAD_REQUEST",
message: "Only tasks and approvals can be assigned",
});
expect(update).not.toHaveBeenCalled();
expect(emitTaskAssigned).not.toHaveBeenCalled();
});
it("reassigns a task and emits the assignment event for the new assignee", async () => {
const findUnique = vi.fn().mockResolvedValue({
id: "task_9",
@@ -1365,6 +1590,103 @@ describe("notification.assignTask", () => {
});
expect(emitTaskAssigned).not.toHaveBeenCalledWith("user_missing", "task_9");
});
it("returns NOT_FOUND when the task disappears before reassignment is persisted", async () => {
const findUnique = vi.fn().mockResolvedValue({
id: "task_9",
category: "TASK",
assigneeId: "user_2",
});
const update = vi.fn().mockRejectedValue(
Object.assign(new Error("Record to update not found"), {
code: "P2025",
}),
);
const db = {
notification: {
findUnique,
update,
},
};
const caller = createManagerCaller(db);
await expect(caller.assignTask({ id: "task_9", assigneeId: "user_4" })).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Task not found",
});
expect(findUnique).toHaveBeenCalledWith({ where: { id: "task_9" } });
expect(update).toHaveBeenCalledWith({
where: { id: "task_9" },
data: { assigneeId: "user_4" },
});
expect(emitTaskAssigned).not.toHaveBeenCalled();
});
});
describe("notification.executeTaskAction", () => {
it("rejects dismissed tasks before executing their domain action", async () => {
const updateAssignment = vi.fn();
const db = withUserLookup({
notification: {
findFirst: vi.fn().mockResolvedValue({
id: "task_1",
userId: "user_1",
assigneeId: null,
taskAction: "confirm_assignment:assign_1",
taskStatus: "DISMISSED",
}),
update: vi.fn(),
},
assignment: {
findUnique: vi.fn(),
update: updateAssignment,
},
});
const caller = createAdminCaller(db);
await expect(caller.executeTaskAction({ id: "task_1" })).rejects.toMatchObject({
code: "PRECONDITION_FAILED",
message: "This task has been dismissed",
});
expect(updateAssignment).not.toHaveBeenCalled();
expect(db.notification.update).not.toHaveBeenCalled();
expect(emitTaskCompleted).not.toHaveBeenCalled();
});
it("rejects task action execution when transactional persistence support is unavailable", async () => {
const updateVacation = vi.fn();
const db = withUserLookup({
notification: {
findFirst: vi.fn().mockResolvedValue({
id: "task_1",
userId: "user_1",
assigneeId: null,
taskAction: "approve_vacation:vac_1",
taskStatus: "OPEN",
}),
update: vi.fn(),
},
vacation: {
findUnique: vi.fn(),
update: updateVacation,
},
});
const caller = createAdminCaller(db);
await expect(caller.executeTaskAction({ id: "task_1" })).rejects.toMatchObject({
code: "INTERNAL_SERVER_ERROR",
message: "Task action execution requires transactional persistence support.",
});
expect(updateVacation).not.toHaveBeenCalled();
expect(db.notification.update).not.toHaveBeenCalled();
expect(emitTaskCompleted).not.toHaveBeenCalled();
});
});
// ─── reminders ──────────────────────────────────────────────────────────────
@@ -1467,6 +1789,28 @@ describe("notification.updateReminder", () => {
},
});
});
it("returns NOT_FOUND when the reminder is missing or belongs to another user", async () => {
const update = vi.fn();
const db = withUserLookup({
notification: {
findFirst: vi.fn().mockResolvedValue(null),
update,
},
});
const caller = createProtectedCaller(db);
await expect(caller.updateReminder({
id: "rem_missing",
title: "Updated reminder",
})).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Reminder not found or you do not have permission",
});
expect(update).not.toHaveBeenCalled();
});
});
describe("notification.deleteReminder", () => {
@@ -1492,6 +1836,25 @@ describe("notification.deleteReminder", () => {
});
expect(deleteFn).toHaveBeenCalledWith({ where: { id: "rem_1" } });
});
it("returns NOT_FOUND when the reminder is missing or belongs to another user", async () => {
const deleteFn = vi.fn();
const db = withUserLookup({
notification: {
findFirst: vi.fn().mockResolvedValue(null),
delete: deleteFn,
},
});
const caller = createProtectedCaller(db);
await expect(caller.deleteReminder({ id: "rem_missing" })).rejects.toMatchObject({
code: "NOT_FOUND",
message: "Reminder not found or you do not have permission",
});
expect(deleteFn).not.toHaveBeenCalled();
});
});
describe("notification.listReminders", () => {