src/features/reviews/intake-command.ts
Linked repository file from this build.
import {
newReviewKey,
reviewIdentity,
sameReviewIdentity,
type ReviewIdentity,
} from "./review-key";
import { captureReceivedSnapshot } from "./commands";
import type { SnapPolicy } from "@/programs/snap-negative/policy";
import { initialPolicy, policyForMonth } from "@/programs/snap-negative/policy";
import { parseSnapNegativeBatch } from "@/lib/import/snap-negative";
import { assertReviewAccess, can } from "@/lib/auth/scope";
import { roleLabels, type Actor } from "./types";
import type { SnapReview } from "@/programs/snap-negative/types";
import type { ReviewStore, StoredReview } from "./review-store";
import { appendReview, StaleReviewError } from "./persistence";
import { RuleError } from "@/lib/errors";
import { actorRef } from "@/lib/auth/actor";
export type IntakeFiles = Parameters<typeof parseSnapNegativeBatch>[0];
/** Intake command: source facts are reconstructed on the server, never accepted as a case payload. */
export async function promoteSnapNegative(
store: ReviewStore,
input: IntakeFiles,
identity: ReviewIdentity,
actor: Actor,
expectedVersion: number | null,
requestId: string,
loadPolicies: () => Promise<SnapPolicy[]> = async () => [initialPolicy],
): Promise<StoredReview> {
if (!can(actor, "import"))
throw new RuleError("Only program manager, admin and statistics can import reviews.");
const parsed = parseSnapNegativeBatch(input);
if (parsed.findings.length) throw new RuleError("Resolve all intake findings before promotion.");
const imported = parsed.cases.find((review) => {
const candidate = reviewIdentity(review);
return sameReviewIdentity(candidate, identity);
});
if (!imported) throw new RuleError("Select a sampled review from this batch.");
const repeated = await store.findRequest(requestId);
if (repeated) {
if (!sameReviewIdentity(reviewIdentity(repeated.review), reviewIdentity(imported)))
throw new RuleError("Request belongs to another review.");
assertReviewAccess(actor, repeated.review);
return repeated;
}
assertReviewAccess(actor, imported);
const current = await store.findBusiness(identity);
if (current) assertReviewAccess(actor, current.review);
if (current && current.version !== expectedVersion) throw new StaleReviewError(current);
if (!current && expectedVersion !== null)
throw new RuleError("Review no longer exists. Preview again.");
if (current?.review.state === "dropped")
throw new RuleError("You cannot refresh a Dropped review.");
const at = new Date().toISOString();
const policy =
current?.review.policy ?? policyForMonth(imported.sampleMonth, await loadPolicies());
const review: SnapReview = {
...imported,
policyId: policy.id,
policy,
calcVersion: current?.review.calcVersion ?? imported.calcVersion,
checkVersion: current?.review.checkVersion ?? imported.checkVersion,
id: current?.review.id ?? newReviewKey(),
activity: [
...(current?.review.activity ?? []),
{
id: requestId,
kind: "edit" as const,
actor: actorRef(actor),
createdAt: at,
description: `${actor.name} (${roleLabels[actor.role]}) ${current ? "refreshed" : "created"} a synthetic SNAP Negative review from sample delimited files; examiner completion required.`,
from: current?.review.state,
to: "new_active" as const,
},
],
intake: { batchId: requestId, sources: input },
};
review.receivedSnapshots = { examiner: captureReceivedSnapshot(review) };
const result = {
review,
version: (current?.version ?? -1) + 1,
actor: actorRef(actor),
requestId,
savedAt: at,
};
return appendReview(store, result, {
expectedVersion,
actors: [actor],
newIdentity: current ? undefined : identity,
previous: current?.review,
});
}