src/features/reviews/permissions.ts
Linked repository file from this build.
import { can, canAccessReview } from "@/lib/auth/scope";
import { sameActor } from "@/lib/auth/actor";
import { hasOpenStoredFindings } from "@/programs/snap-negative/validation";
import type { SnapReview } from "@/programs/snap-negative/types";
import type { Actor } from "./types";
/** Review rules that depend on both the role and the review state. The UI and execute share them. */
export function canEdit(review: SnapReview, actor: Actor): boolean {
if (!canAccessReview(actor, review)) return false;
return (
actor.role === "examiner" && (review.state === "new_active" || review.state === "needs_changes")
);
}
export function canAddNote(actor: Actor): boolean {
return can(actor, "addNotes");
}
export function canUpdateNote(review: SnapReview, actor: Actor, noteId: string): boolean {
if (!canAddNote(actor)) return false;
const note = review.notes.find((entry) => entry.id === noteId);
if (!note) return false;
const kind = note.kind ?? "ordinary";
if (sameActor(note.actor, actor)) return true;
if (can(actor, "seniorReview") && kind === "ordinary") return true;
return false;
}
export function canRefuseFinding(actor: Actor): boolean {
return can(actor, "seniorReview");
}
export function canSubmitPolicyDecision(review: SnapReview, actor: Actor): boolean {
return actor.role === "pec" && review.state === "awaiting_pec_approval";
}
export function openFindingsBlockApproval(review: SnapReview): boolean {
return hasOpenStoredFindings(review);
}