import { ok, err, UnauthenticatedError, type CallerContext, type ReadonlyDB, } from "@tailor-platform/erp-kit/core"; import type { DB } from "../generated/kysely-tailordb"; export interface GetNotificationInput { id: string; } /** * Returns a Notification by id when the caller is its recipient; otherwise null (no existence oracle). */ export async function run(db: ReadonlyDB, input: GetNotificationInput, ctx: CallerContext) { // Every result here is scoped to the caller, so there is nothing to return when // there is no caller. Queries carry no permission gate of their own. const { actorId } = ctx; if (actorId === null) return err(new UnauthenticatedError()); const notification = await db .selectFrom("Notification") .selectAll() .where("id", "=", input.id) .executeTakeFirst(); if (!notification) { return ok({ notification: null }); } // Self-scope: a notification owned by another user is reported exactly like // a missing one (null) so callers cannot enumerate foreign notification ids. if (notification.recipientUserId !== actorId) { return ok({ notification: null }); } return ok({ notification }); }