From 77ab6fb94a17ea1486f999ae4490e5fa8db1eeb9 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Tue, 14 Apr 2026 11:48:33 -0700 Subject: [PATCH] feat: add getTemplates, getRoleCandidates, buildRecipe to recipesAPI client --- frontend/src/services/api.ts | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 857c3f9..4865f4f 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -503,6 +503,40 @@ export interface Staple { dietary_tags: string[] } +// ── Build Your Own types ────────────────────────────────────────────────── + +export interface AssemblyRoleOut { + display: string + required: boolean + keywords: string[] + hint: string +} + +export interface AssemblyTemplateOut { + id: string + title: string + icon: string + descriptor: string + role_sequence: AssemblyRoleOut[] +} + +export interface RoleCandidateItem { + name: string + in_pantry: boolean + tags: string[] +} + +export interface RoleCandidatesResponse { + compatible: RoleCandidateItem[] + other: RoleCandidateItem[] + available_tags: string[] +} + +export interface BuildRequest { + template_id: string + role_overrides: Record +} + // ========== Recipes API ========== export const recipesAPI = { @@ -518,6 +552,28 @@ export const recipesAPI = { const response = await api.get('/staples/', { params: dietary ? { dietary } : undefined }) return response.data }, + async getTemplates(): Promise { + const response = await api.get('/recipes/templates') + return response.data + }, + async getRoleCandidates( + templateId: string, + role: string, + priorPicks: string[] = [], + ): Promise { + const response = await api.get('/recipes/template-candidates', { + params: { + template_id: templateId, + role, + prior_picks: priorPicks.join(','), + }, + }) + return response.data + }, + async buildRecipe(req: BuildRequest): Promise { + const response = await api.post('/recipes/build', req) + return response.data + }, } // ========== Settings API ==========