Public Access
- Create backend/app/api/orchestrate.py — new router for workflow steps
(scrape, generate, email, reminder, deadline, finalize) without admin auth.
- Remove orchestrate endpoints from backend/app/api/admin.py.
- Register orchestrate router in main.py under /api/orchestrate.
- Update frontend api/index.ts to call /orchestrate/{step} instead of
/admin/orchestrate/{step}.
This lets family members trigger vote emails without an admin bearer token.
76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
import axios from 'axios'
|
|
|
|
const API_BASE = import.meta.env.VITE_API_URL || '/api'
|
|
|
|
const api = axios.create({
|
|
baseURL: API_BASE,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
withCredentials: true,
|
|
})
|
|
|
|
export const mealPlannerApi = {
|
|
auth: {
|
|
login: (password: string) => api.post('/auth/login', { password }),
|
|
logout: () => api.post('/auth/logout'),
|
|
},
|
|
|
|
profile: {
|
|
get: () => api.get('/profile'),
|
|
update: (data: any) => api.put('/profile', data),
|
|
getMembers: () => api.get('/profile/members'),
|
|
addMember: (data: any) => api.post('/profile/members', data),
|
|
deleteMember: (id: string) => api.delete(`/profile/members/${id}`),
|
|
},
|
|
|
|
recipes: {
|
|
list: (params?: any) => api.get('/recipes', { params }),
|
|
get: (id: string) => api.get(`/recipes/${id}`),
|
|
create: (data: any) => api.post('/recipes', data),
|
|
delete: (id: string) => api.delete(`/recipes/${id}`),
|
|
listIngredients: () => api.get('/recipes/ingredients'),
|
|
createIngredient: (data: any) => api.post('/recipes/ingredients', data),
|
|
},
|
|
|
|
meals: {
|
|
getPlanned: () => api.get('/meals'),
|
|
get: (id: string) => api.get(`/meals/${id}`),
|
|
getItem: (id: string) => api.get(`/meals/items/${id}`),
|
|
create: (data: any) => api.post('/meals', data),
|
|
lock: (id: string) => api.post(`/meals/${id}/lock`),
|
|
getVotePage: (itemId: string, token: string) => api.get(`/meals/items/${itemId}/vote/${token}`),
|
|
submitVote: (itemId: string, token: string, data: any) => api.post(`/meals/items/${itemId}/vote/${token}`, data),
|
|
swapItem: (itemId: string, newRecipeId: string) => api.post(`/meals/items/${itemId}/swap?new_recipe_id=${newRecipeId}`),
|
|
},
|
|
|
|
pantry: {
|
|
list: () => api.get('/pantry'),
|
|
add: (data: any) => api.post('/pantry', data),
|
|
update: (id: string, data: any) => api.put(`/pantry/${id}`, data),
|
|
remove: (id: string) => api.delete(`/pantry/${id}`),
|
|
},
|
|
|
|
shoppingList: {
|
|
get: () => api.get('/shopping-list'),
|
|
getPrint: () => api.get('/shopping-list/print'),
|
|
},
|
|
|
|
admin: {
|
|
triggerScrape: (source?: string, type?: string) => api.post('/admin/scrape', null, { params: { source, scrape_type: type } }),
|
|
getLogs: (params?: any) => api.get('/admin/logs', { params }),
|
|
getLog: (id: string) => api.get(`/admin/logs/${id}`),
|
|
getEmailLogs: (params?: any) => api.get('/admin/email-logs', { params }),
|
|
getMealPlans: (params?: any) => api.get('/admin/meal-plans', { params }),
|
|
getStats: () => api.get('/admin/stats'),
|
|
testEmail: (email: string) => api.post('/admin/test-email', null, { params: { email } }),
|
|
triggerOrchestrate: (step: string, weekStart?: string) => api.post(`/orchestrate/${step}`, null, { params: { week_start: weekStart } }),
|
|
},
|
|
|
|
feedback: {
|
|
get: (mealPlanItemId: string) => api.get(`/feedback/${mealPlanItemId}`),
|
|
create: (data: any) => api.post('/feedback', data),
|
|
},
|
|
}
|
|
|
|
export default api |