Add create-meta-recipe endpoint with nested slots/options/bases

- POST /api/create-meta-recipe/ creates full meta-recipe in one call
- PUT /api/create-meta-recipe/ updates existing (requires id)
- Auto-resolves ingredients by name/alias, creates new if not found
- Returns full nested response with _created_ingredients list
- New writable serializers: MetaRecipeWriteSerializer, SlotWriteSerializer, etc.
This commit is contained in:
Caine
2026-04-02 17:51:12 +01:00
parent 27f91fb877
commit 189d72b797
4 changed files with 2465 additions and 0 deletions
+41
View File
@@ -75,6 +75,47 @@ class MetaRecipeSerializer(serializers.ModelSerializer):
fields = "__all__"
# --- Writable nested meta-recipe ---
class SlotOptionWriteSerializer(serializers.Serializer):
ingredient_name = serializers.CharField()
ingredient_id = serializers.IntegerField(required=False)
quantity_per_serving = serializers.DecimalField(max_digits=8, decimal_places=2)
unit = serializers.CharField()
notes = serializers.CharField(required=False, default="", allow_blank=True)
# For auto-creating ingredients
default_unit = serializers.CharField(required=False)
tags = serializers.ListField(child=serializers.CharField(), required=False, default=list)
shelf_life_days = serializers.IntegerField(required=False, allow_null=True, default=None)
class SlotWriteSerializer(serializers.Serializer):
name = serializers.CharField()
required = serializers.BooleanField(default=True)
max_choices = serializers.IntegerField(default=1)
options = SlotOptionWriteSerializer(many=True)
class BaseIngredientWriteSerializer(serializers.Serializer):
ingredient_name = serializers.CharField()
ingredient_id = serializers.IntegerField(required=False)
quantity_per_serving = serializers.DecimalField(max_digits=8, decimal_places=2)
unit = serializers.CharField()
class MetaRecipeWriteSerializer(serializers.Serializer):
name = serializers.CharField()
method = serializers.CharField()
prep_time_mins = serializers.IntegerField(required=False, allow_null=True, default=None)
cook_time_mins = serializers.IntegerField(required=False, allow_null=True, default=None)
default_servings = serializers.IntegerField(default=2)
gear_needed = serializers.CharField(required=False, default="", allow_blank=True)
tags = serializers.ListField(child=serializers.CharField(), required=False, default=list)
slots = SlotWriteSerializer(many=True, required=False, default=list)
base_ingredients = BaseIngredientWriteSerializer(many=True, required=False, default=list)
# --- Fixed Recipe nested serializers ---