src/programs/snap-negative/seed.ts
Linked repository file from this build.
import { fixtureReviewKey } from "./fixture-key";
import {
DEMO_BASELINE_AS_OF,
DEMO_BASELINE_PER_MONTH,
DEMO_GENERATOR_SEED,
DEMO_REVIEW_NUMBER,
DEMO_SAMPLE_MONTH,
} from "./constants";
import { deriveFfyFromSampleMonth } from "@/features/reviews/downstream";
import { CURRENT_CALC_VERSION, CURRENT_CHECK_VERSION } from "./rule-versions";
import { normalizeReviewAnswers } from "./field-catalog";
import { generateSeedBatch, type SeedGeneratorOptions } from "./seed-generator";
import type { Scenario, SnapReview } from "./types";
export {
DEMO_REVIEW_NUMBER,
DEMO_SAMPLE_MONTH,
DEMO_GENERATOR_SEED,
DEMO_BASELINE_PER_MONTH,
DEMO_BASELINE_AS_OF,
} from "./constants";
/** Shared generator options for db:seed and Reset demo. */
export function resetBaselineBatchOptions(
overrides: Partial<SeedGeneratorOptions> = {},
): SeedGeneratorOptions {
return {
ffyFrom: deriveFfyFromSampleMonth(DEMO_SAMPLE_MONTH),
ffyTo: deriveFfyFromSampleMonth(DEMO_SAMPLE_MONTH),
perMonth: DEMO_BASELINE_PER_MONTH,
seed: DEMO_GENERATOR_SEED,
sampleMonths: [DEMO_SAMPLE_MONTH],
preserveReviewNumbers: [],
asOf: new Date(DEMO_BASELINE_AS_OF),
...overrides,
};
}
export function generateResetBaselineBatch(overrides: Partial<SeedGeneratorOptions> = {}) {
return generateSeedBatch(resetBaselineBatchOptions(overrides));
}
function normalizeDemoSeed(generated: SnapReview): SnapReview {
return {
...generated,
id: fixtureReviewKey("60001"),
revision: 0,
state: "new_active",
outcome: "",
examiner: "101",
supervisor: "201",
notes: [],
documents: [],
activity: [],
validation: undefined,
pecDecision: undefined,
supervisorApproved: undefined,
pecApproved: undefined,
memoApproved: undefined,
errorSummaryReleased: undefined,
dropApproved: undefined,
dropKind: undefined,
memos: undefined,
caoResponse: undefined,
caoResponseDeadline: undefined,
receivedSnapshots: { examiner: generated.receivedSnapshots!.examiner },
lineage: undefined,
intake: undefined,
facts: {
...generated.facts,
final: undefined,
},
};
}
function scenario(wages: number): Scenario {
return {
populated: true,
householdSize: 3,
income: [
{
id: "wages",
memberId: "member-1",
typeCode: "11",
category: "earned",
amountCents: wages * 100,
expensesCents: 0,
description: "Fictional shop wages",
},
{
id: "support",
memberId: "member-2",
typeCode: "31",
category: "unearned",
amountCents: 20000,
expensesCents: 0,
description: "Fictional support; demo source code",
},
],
medicalDeductionCents: 0,
dependentCareCents: 10000,
childSupportCents: 0,
rentCents: 80000,
taxesInsuranceCents: 0,
installationCents: 0,
otherShelterCents: 0,
sua: "heating",
elderlyDisabled: false,
categoricalEligibility: false,
homeless: false,
};
}
/** Populated computation scenarios for tests and E2E submit helpers. */
export function demoScenarioTemplate(wages: number): Scenario {
return scenario(wages);
}
/** Minimal import/template review used when constructing imported cases in tests. */
export function createImportTemplate(): SnapReview {
return {
calcVersion: CURRENT_CALC_VERSION,
checkVersion: CURRENT_CHECK_VERSION,
id: fixtureReviewKey("60001"),
reviewNumber: DEMO_REVIEW_NUMBER,
caseNumber: "SYN-200445566",
program: "SNAP",
subtype: "negative",
sampleMonth: "2026-04",
clientName: "Taylor Brooks (fictional)",
address: "100 Example Lane, Harrisburg, PA 17101",
county: "Dauphin",
district: "01",
localAgency: "Demo CAO",
examiner: "101",
supervisor: "201",
state: "new_active",
outcome: "error",
revision: 0,
facts: {
negativeAction: "Denial",
noticeDate: "2026-03-20",
actionDate: "2026-04-01",
inputsRevision: 0,
members: [
{ id: "member-1", line: "01", name: "Taylor Brooks", relationship: "Head" },
{ id: "member-2", line: "02", name: "Robin Brooks", relationship: "Child" },
{ id: "member-3", line: "03", name: "Jamie Brooks", relationship: "Child" },
],
scenarios: { eligibility: scenario(5000), compI: scenario(1800), compII: scenario(2300) },
answers: normalizeReviewAnswers({
actionType: "1",
narrative:
"The fictional CAO used income that differed from the examiner verification. Review the sample-month and last-action evidence.",
}),
},
notes: [],
documents: [],
activity: [],
};
}
/** @deprecated Use createImportTemplate() or createDemoSeed() explicitly. */
export function createSeed(): SnapReview {
return createImportTemplate();
}
/** Generated demo baseline for review 60001 (reset, first load, and db:seed). */
export function createDemoSeed(): SnapReview {
const generated = generateResetBaselineBatch({ perMonth: 1 }).reviews.find(
(review) => review.reviewNumber === DEMO_REVIEW_NUMBER,
);
if (!generated) {
throw new Error(`Demo seed generator did not produce review ${DEMO_REVIEW_NUMBER}.`);
}
return normalizeDemoSeed(generated);
}
/** Minimal completed-review answers for tests and demos. */
export function completedReviewAnswers(
patch: Partial<ReturnType<typeof normalizeReviewAnswers>> = {},
) {
return normalizeReviewAnswers({
actionType: "1",
caseClassification: "1",
disposition: "1",
finding: "2",
recordedReason: "11",
recordedReasonAccuracy: "2",
noticeRequirement: "1",
noticeLanguage: "1",
noticeClearUnderstandable: "2",
noticeReasonToHh: "11",
noticeReasonAccuracy: "21",
missedInterviewNotice: "3",
contactRequest: "3",
verificationRequest: "3",
periodicReport: "3",
actionTimeliness: "1",
noticeTimeliness: "1",
contactResponse: "03",
actionInitiatedBy: "04",
narrative: "Income verification did not support the recorded denial reason.",
...patch,
});
}