src/lib/db/inbox-events.ts
Linked repository file from this build.
import { reviewKey } from "@/features/reviews/review-key";
import type { StoredReview } from "@/features/reviews/review-store";
import type { SnapReview } from "@/programs/snap-negative/types";
export type InboxEventKind =
| "distributed"
| "document_added"
| "changes_requested"
| "approved"
| "dropped"
| "pec_decision"
| "appointment_changed";
/** Compare durable state so retries and ordinary edits cannot create extra news. */
export function eventKinds(
previous: SnapReview | undefined,
current: SnapReview,
now: string,
): InboxEventKind[] {
if (!previous)
return current.state === "new_active" && current.sampleMonth.slice(0, 7) === now.slice(0, 7)
? ["distributed"]
: [];
const kinds: InboxEventKind[] = [];
if (previous.examiner !== current.examiner) kinds.push("distributed");
if (
current.documents.some((document) => !previous.documents.some((old) => old.id === document.id))
)
kinds.push("document_added");
if (current.state !== previous.state) {
if (current.state === "needs_changes") kinds.push("changes_requested");
if (current.state === "dropped") kinds.push("dropped");
}
if (
(["supervisorApproved", "memoApproved", "errorSummaryReleased"] as const).some(
(flag) => current[flag] && JSON.stringify(current[flag]) !== JSON.stringify(previous[flag]),
)
)
kinds.push("approved");
if (
current.pecDecision &&
JSON.stringify(current.pecDecision) !== JSON.stringify(previous.pecDecision)
)
kinds.push("pec_decision");
if ((current.appointment ?? "") !== (previous.appointment ?? ""))
kinds.push("appointment_changed");
return kinds;
}
export function eventsForSave(previous: SnapReview | undefined, value: StoredReview) {
const recipients = [...new Set([value.review.examiner, value.review.supervisor])].filter(
(staffId) => staffId && staffId !== value.actor.staffId,
);
return eventKinds(previous, value.review, value.savedAt).flatMap((kind) =>
recipients.map((staffId) => ({
id: JSON.stringify([value.requestId, staffId, kind]),
reviewKey: reviewKey(value.review),
reviewNumber: value.review.reviewNumber,
staffId,
kind,
actorRole: value.actor.role,
createdAt: value.savedAt,
})),
);
}