src/programs/snap-negative/types.ts
Linked repository file from this build.
import type { ReviewRecord } from "@/features/reviews/types";
import type { SnapPolicy } from "./policy";
export type ScenarioId = "eligibility" | "compI" | "compII";
export interface HouseholdMember {
id: string;
line: string;
name: string;
relationship: string;
}
export interface IncomeStream {
id: string;
memberId: string;
typeCode: string;
category: "earned" | "unearned" | "self_employment";
amountCents: number;
expensesCents: number;
selfEmploymentKind?: "farm" | "non_farm";
description: string;
}
export type SuaType = "heating" | "non_heating" | "limited" | "telephone" | "none";
export interface Scenario {
populated: boolean;
householdSize: number;
income: IncomeStream[];
educationGrantCents?: number;
educationExpensesCents?: number;
applicationDay?: number | null;
medicalDeductionCents: number;
dependentCareCents: number;
childSupportCents: number;
rentCents: number;
taxesInsuranceCents: number;
installationCents: number;
otherShelterCents: number;
sua: SuaType;
elderlyDisabled: boolean;
categoricalEligibility: boolean;
homeless: boolean;
}
export interface ComputationResult {
policyId: string;
householdSize: number;
earnedCents: number;
selfEmploymentProfitCents?: number;
selfEmploymentLossCents?: number;
educationNetCents?: number;
earnedAndEducationCents?: number;
monthlyBenefitCents?: number;
unearnedCents: number;
grossCents: number;
grossLimitCents: number;
earnedDeductionCents: number;
standardDeductionCents: number;
adjustedIncomeCents: number;
suaCents: number;
shelterCents: number;
shelterDeductionCents: number;
netCents: number;
netLimitCents: number;
allotmentCents: number;
benefitCents: number;
eligible: boolean;
}
export interface FinalResult {
/** Snapshot of selected inputs; absent only on older saved reviews. */
inputs?: Scenario;
scenario: "compI" | "compII";
reason: string;
result: ComputationResult;
errorCents: number;
income: IncomeStream[];
inputsRevision: number;
}
export interface ReviewVariance {
element: string;
nature: string;
}
export interface ReviewAnswers {
telephone: string;
actualAddress: string;
dateAssigned: string;
dateCompleted: string;
dateCleared: string;
stratum: string;
actionType: string;
caseClassification: string;
disposition: string;
nstrReason: string;
finding: string;
recordedReason: string;
recordedReasonAccuracy: string;
noticeRequirement: string;
noticeLanguage: string;
noticeClearUnderstandable: string;
noticeReasonToHh: string;
noticeReasonAccuracy: string;
missedInterviewNotice: string;
contactRequest: string;
verificationRequest: string;
periodicReport: string;
actionTimeliness: string;
daysActionEarlyLate: string;
noticeTimeliness: string;
daysNoticeLate: string;
contactResponse: string;
actionInitiatedBy: string;
narrative: string;
narrativePreset: string;
variances: ReviewVariance[];
processingDistrict1: string;
processingDistrict2: string;
homeCountyArea: string;
homeCountyDigit1: string;
homeCountyDigit2: string;
homeCountyDistrict1: string;
homeCountyDistrict2: string;
fs75: string;
rejectionReasonEsap: string;
workerExperience: string;
/** @deprecated Replaced by timeliness fields. Ignored by validation. */
timelinessResponse?: string;
}
export interface SnapFacts {
negativeAction: string;
caoIssuedBenefitCents?: number;
noticeDate: string;
actionDate: string;
/** Optional leftover stored field. Not a review question and not a computation mode. */
paCap?: "no" | "yes" | "unknown";
members: HouseholdMember[];
scenarios: Record<ScenarioId, Scenario>;
inputsRevision: number;
answers: ReviewAnswers;
final?: FinalResult;
}
export interface SnapNegativeSources {
fileNames?: { closedSuspended?: string; rejected?: string };
closedSuspended: string;
rejected: string;
/** Reserved for other programs; SNAP Negative rejects nonempty person files. */
}
export interface SnapNegativeLineage {
sourceSystem: "sample_delim";
role: "closed_suspended" | "rejected" | "file_of_records";
fileName: string;
rowNumber: number;
rawText: string;
}
export interface SnapReview extends ReviewRecord<SnapFacts> {
policyId?: string;
policy?: SnapPolicy;
calcVersion: string;
checkVersion: string;
lineage?: SnapNegativeLineage[];
intake?: { batchId: string; sources: SnapNegativeSources };
}
/** Fields read by the shared downstream eligibility checks. */
export type EligibilityReview = Pick<
SnapReview,
"state" | "outcome" | "checkVersion" | "revision" | "validation" | "errorSummaryReleased"
> & {
facts: Pick<SnapReview["facts"], "answers" | "inputsRevision"> & {
final?: Pick<FinalResult, "inputsRevision">;
};
};