src/features/reviews/income-validation.ts
Linked repository file from this build.
import { MAX_MONEY_CENTS } from "@/programs/snap-negative/input-limits";
import type { HouseholdMember, IncomeStream } from "@/programs/snap-negative/types";
export type IncomeField =
| "memberId"
| "typeCode"
| "category"
| "selfEmploymentKind"
| "amountCents"
| "expensesCents";
function moneyError(cents: number) {
return !Number.isSafeInteger(cents) || cents < 0 || cents > MAX_MONEY_CENTS
? "Enter $0–$1,000,000 with up to two decimal places."
: undefined;
}
export function incomeFieldErrors(
draft: IncomeStream,
members: HouseholdMember[],
): Partial<Record<IncomeField, string>> {
const errors: Partial<Record<IncomeField, string>> = {};
if (!members.some((member) => member.id === draft.memberId))
errors.memberId = "Choose a household member.";
if (!draft.typeCode.trim()) errors.typeCode = "Enter an income type.";
if (!["earned", "unearned", "self_employment"].includes(draft.category))
errors.category = "Choose an income category.";
errors.amountCents = moneyError(draft.amountCents);
if (draft.category === "self_employment") {
if (!["farm", "non_farm"].includes(draft.selfEmploymentKind ?? ""))
errors.selfEmploymentKind = "Choose a business type.";
errors.expensesCents = moneyError(draft.expensesCents);
}
return errors;
}