This commit is contained in:
Cayden Schwechten 2026-10-31 20:44:29 -05:00
commit c19b910c36
80 changed files with 16134 additions and 0 deletions

27
app/actions.ts Normal file
View file

@ -0,0 +1,27 @@
"use server";
import type { FillMode, GeneratePlanInput, GeneratePlanResult } from "@/app/types";
import { generatePlan } from "@/app/lib/planner";
import { sanitizeState } from "@/app/lib/sanitize";
// ---------------------------------------------------------------------------
// Server Actions.
//
// Note on the split: live cost recalculation runs in the BROWSER (same pure
// functions from lib/), so every slider tweak updates instantly with no round
// trip. Generation runs HERE so that, once real prices exist, the price API
// key and fetch live server-side only.
//
// Server Actions are public HTTP endpoints, so input goes through the same
// sanitizer as saved state (lib/sanitize.ts) rather than being trusted.
// ---------------------------------------------------------------------------
export async function generateMealPlanAction(input: GeneratePlanInput): Promise<GeneratePlanResult> {
const state = sanitizeState(input?.state);
const fillMode: FillMode = input?.fillMode === "all" ? "all" : "empty";
const seed = Number.isFinite(input?.seed) ? Math.floor(input.seed) : Date.now();
// Real price lookups would go here: fetch → build a SnapshotPriceProvider
// → pass it through generatePlan/buildGroceryList.
return generatePlan(state, fillMode, seed);
}