feat(api): POST /api/recipes fuer Scratch-Insert aus Foto-Import
This commit is contained in:
61
src/routes/api/recipes/+server.ts
Normal file
61
src/routes/api/recipes/+server.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { RequestHandler } from './$types';
|
||||
import { json } from '@sveltejs/kit';
|
||||
import { z } from 'zod';
|
||||
import { getDb } from '$lib/server/db';
|
||||
import { validateBody } from '$lib/server/api-helpers';
|
||||
import { insertRecipe } from '$lib/server/recipes/repository';
|
||||
|
||||
const IngredientSchema = z.object({
|
||||
position: z.number().int().nonnegative(),
|
||||
quantity: z.number().nullable(),
|
||||
unit: z.string().max(30).nullable(),
|
||||
name: z.string().min(1).max(200),
|
||||
note: z.string().max(300).nullable(),
|
||||
raw_text: z.string().max(500),
|
||||
section_heading: z.string().max(200).nullable()
|
||||
});
|
||||
|
||||
const StepSchema = z.object({
|
||||
position: z.number().int().positive(),
|
||||
text: z.string().min(1).max(4000)
|
||||
});
|
||||
|
||||
const CreateRecipeSchema = z.object({
|
||||
title: z.string().min(1).max(200),
|
||||
description: z.string().max(2000).nullable(),
|
||||
servings_default: z.number().int().nonnegative().nullable(),
|
||||
servings_unit: z.string().max(30).nullable(),
|
||||
prep_time_min: z.number().int().nonnegative().nullable(),
|
||||
cook_time_min: z.number().int().nonnegative().nullable(),
|
||||
total_time_min: z.number().int().nonnegative().nullable(),
|
||||
ingredients: z.array(IngredientSchema),
|
||||
steps: z.array(StepSchema)
|
||||
});
|
||||
|
||||
// Anlegen eines kompletten Rezepts aus Scratch. Wird vom Foto-Import-Flow
|
||||
// genutzt, nachdem der Nutzer im Editor die AI-Extraktion geprüft/korrigiert
|
||||
// und auf Speichern getippt hat. Der bestehende /api/recipes/blank-Endpoint
|
||||
// bleibt für den „leer anlegen"-Flow unverändert.
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
const body = await request.json().catch(() => null);
|
||||
const p = validateBody(body, CreateRecipeSchema);
|
||||
const id = insertRecipe(getDb(), {
|
||||
id: null,
|
||||
title: p.title,
|
||||
description: p.description,
|
||||
source_url: null,
|
||||
source_domain: null,
|
||||
image_path: null,
|
||||
servings_default: p.servings_default,
|
||||
servings_unit: p.servings_unit,
|
||||
prep_time_min: p.prep_time_min,
|
||||
cook_time_min: p.cook_time_min,
|
||||
total_time_min: p.total_time_min,
|
||||
cuisine: null,
|
||||
category: null,
|
||||
ingredients: p.ingredients,
|
||||
steps: p.steps,
|
||||
tags: []
|
||||
});
|
||||
return json({ id }, { status: 201 });
|
||||
};
|
||||
Reference in New Issue
Block a user