init
This commit is contained in:
commit
c19b910c36
80 changed files with 16134 additions and 0 deletions
27
app/actions.ts
Normal file
27
app/actions.ts
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue