fix: align frontend API calls with backend routes and types

- Backend: rename routes /mealplan→/mealplans, /shoppinglist→/shopping
- Backend: simplify swap/reroll to entry-centric endpoints (by entryId)
- Frontend: fix all interfaces to use string GUIDs instead of numbers
- Frontend: fix field names (weekStart, date, totalAmount) to match backend JSON
- Frontend: shopping toggle by itemName instead of non-existent id
- Frontend: handle 204 No Content on DELETE responses
- Docker-compose: use env vars for DB credentials

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 06:49:41 +00:00
parent f58782774b
commit 1885abee64
10 changed files with 64 additions and 75 deletions

View File

@@ -3,15 +3,15 @@ import { ref } from 'vue'
import { useApi } from '../composables/useApi'
export interface Ingredient {
id?: number
id?: string
name: string
amount: number
unit: string
category: string
amount: number | null
unit: string | null
category: string | null
}
export interface Recipe {
id: number
id: string
title: string
imageUrl?: string
instructions?: string
@@ -19,25 +19,23 @@ export interface Recipe {
}
export interface MealPlanEntry {
id: number
id: string
date: string
dayOfWeek: number
recipeId: number
recipeId: string
recipe: Recipe
}
export interface MealPlan {
id: number
weekStartDate: string
id: string
weekStart: string
entries: MealPlanEntry[]
}
export interface ShoppingItem {
id: number
name: string
amount: number
unit: string
category: string
totalAmount: number | null
unit: string | null
category: string | null
isChecked: boolean
}
@@ -77,7 +75,7 @@ export const useMealPlanStore = defineStore('mealPlan', () => {
}
}
async function swapMeal(entryId: number, recipeId: number): Promise<void> {
async function swapMeal(entryId: string, recipeId: string): Promise<void> {
error.value = null
try {
const updated = await api.put<MealPlanEntry>(`/mealplans/entries/${entryId}/swap`, { recipeId })
@@ -92,7 +90,7 @@ export const useMealPlanStore = defineStore('mealPlan', () => {
}
}
async function rerollMeal(entryId: number): Promise<void> {
async function rerollMeal(entryId: string): Promise<void> {
error.value = null
try {
const updated = await api.post<MealPlanEntry>(`/mealplans/entries/${entryId}/reroll`)
@@ -116,13 +114,18 @@ export const useShoppingStore = defineStore('shopping', () => {
const items = ref<ShoppingItem[]>([])
const loading = ref(false)
const error = ref<string | null>(null)
const activeMealPlanId = ref<string | null>(null)
async function fetchItems(mealPlanId?: number | string): Promise<void> {
async function fetchItems(mealPlanId?: string): Promise<void> {
loading.value = true
error.value = null
try {
const path = mealPlanId ? `/shopping/${mealPlanId}` : '/shopping/current'
items.value = await api.get<ShoppingItem[]>(path)
if (mealPlanId) {
activeMealPlanId.value = mealPlanId
items.value = await api.get<ShoppingItem[]>(`/shopping/${mealPlanId}`)
} else {
items.value = []
}
} catch (e) {
if (e instanceof Error && e.message === 'HTTP 404') {
items.value = []
@@ -134,13 +137,13 @@ export const useShoppingStore = defineStore('shopping', () => {
}
}
async function toggleItem(id: number): Promise<void> {
const item = items.value.find(i => i.id === id)
if (!item) return
async function toggleItem(itemName: string): Promise<void> {
const item = items.value.find(i => i.name === itemName)
if (!item || !activeMealPlanId.value) return
const prev = item.isChecked
item.isChecked = !prev
try {
await api.put(`/shopping/${id}/toggle`)
await api.put(`/shopping/${activeMealPlanId.value}/check/${encodeURIComponent(itemName)}`)
} catch {
item.isChecked = prev
error.value = 'Fehler beim Aktualisieren.'
@@ -149,7 +152,7 @@ export const useShoppingStore = defineStore('shopping', () => {
const uncheckedCount = () => items.value.filter(i => !i.isChecked).length
return { items, loading, error, fetchItems, toggleItem, uncheckedCount }
return { items, loading, error, activeMealPlanId, fetchItems, toggleItem, uncheckedCount }
})
export const useRecipesStore = defineStore('recipes', () => {
@@ -177,13 +180,13 @@ export const useRecipesStore = defineStore('recipes', () => {
return created
}
async function updateRecipe(id: number, data: Partial<Omit<Recipe, 'id'>>): Promise<void> {
async function updateRecipe(id: string, data: Partial<Omit<Recipe, 'id'>>): Promise<void> {
const updated = await api.put<Recipe>(`/recipes/${id}`, data)
const idx = recipes.value.findIndex(r => r.id === id)
if (idx !== -1) recipes.value[idx] = updated
}
async function deleteRecipe(id: number): Promise<void> {
async function deleteRecipe(id: string): Promise<void> {
await api.del(`/recipes/${id}`)
recipes.value = recipes.value.filter(r => r.id !== id)
}