{ "openapi": "3.1.0", "info": { "title": "Doof API", "description": "Doof Backend API", "version": "1.0.0" }, "paths": { "/api/v1/products": { "post": { "tags": [ "v1", "products" ], "summary": "Create or fetch a product from a URL", "operationId": "createProduct", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductUrl" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Product" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/recipes/parse": { "get": { "tags": [ "v1", "recipes" ], "summary": "Parse a recipe from a URL", "operationId": "parseRecipe", "parameters": [ { "name": "url", "in": "query", "required": true, "schema": { "type": "string", "title": "Url" } }, { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Recipe-Output" } } } }, "400": { "$ref": "#/components/responses/Problem400" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/recipes/ingredients/parse": { "get": { "tags": [ "v1", "recipes" ], "summary": "Parse raw ingredient lines", "operationId": "parseIngredients", "parameters": [ { "name": "ingredients", "in": "query", "required": true, "schema": { "type": "array", "items": { "type": "string" }, "title": "Array of ingredients to parse" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Ingredient" }, "title": "Response Parseingredients" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/recipes": { "get": { "tags": [ "v1", "recipes" ], "summary": "List recipes (paginated)", "operationId": "listRecipes", "parameters": [ { "name": "q", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional case-insensitive name filter (matches recipe name with SQL LIKE).", "title": "Q" }, "description": "Optional case-insensitive name filter (matches recipe name with SQL LIKE)." }, { "name": "cursor", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Opaque cursor for pagination. Pass the value returned in nextCursor to fetch the next page.", "title": "Cursor" }, "description": "Opaque cursor for pagination. Pass the value returned in nextCursor to fetch the next page." }, { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "maximum": 200, "minimum": 1, "description": "Maximum number of items to return (1-200).", "default": 50, "title": "Limit" }, "description": "Maximum number of items to return (1-200)." } ], "responses": { "200": { "description": "A page of recipes", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Page_Recipe_" }, "example": { "items": [ { "id": 1, "name": "Example Recipe", "link": "https://example.com/recipes/1", "serves": 4, "imageUrls": [], "ingredients": [] } ], "nextCursor": "2", "prevCursor": "0", "total": 1 } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "post": { "tags": [ "v1", "recipes" ], "summary": "Create a new recipe (versioning semantics applied)", "operationId": "createRecipe", "parameters": [ { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Recipe-Input" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Recipe-Output" } } } }, "400": { "$ref": "#/components/responses/Problem400" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/recipes/{recipe_id}": { "get": { "tags": [ "v1", "recipes" ], "summary": "Get a single recipe", "operationId": "getRecipe", "parameters": [ { "name": "recipe_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Recipe Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Recipe-Output" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "delete": { "tags": [ "v1", "recipes" ], "summary": "Soft-delete (hide) a recipe", "operationId": "deleteRecipe", "parameters": [ { "name": "recipe_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Recipe Id" } }, { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Recipe-Output" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/meals/upcoming": { "get": { "tags": [ "v1", "meals" ], "summary": "List upcoming meals in a date range", "operationId": "getUpcomingMeals", "parameters": [ { "name": "from", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time", "title": "From" } }, { "name": "to", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time", "title": "To" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Meal-Output" }, "title": "Response Getupcomingmeals" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/meals/{meal_id}": { "get": { "tags": [ "v1", "meals" ], "summary": "Get a meal by id", "operationId": "getMeal", "parameters": [ { "name": "meal_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Meal Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Output" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "put": { "tags": [ "v1", "meals" ], "summary": "Update an existing meal", "operationId": "updateMeal", "parameters": [ { "name": "meal_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Meal Id" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Input" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Output" } } } }, "400": { "$ref": "#/components/responses/Problem400" }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "delete": { "tags": [ "v1", "meals" ], "summary": "Delete a meal", "operationId": "deleteMeal", "parameters": [ { "name": "meal_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Meal Id" } }, { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Output" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/meals": { "post": { "tags": [ "v1", "meals" ], "summary": "Create a new meal", "operationId": "createMeal", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Input" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Output" } } } }, "400": { "$ref": "#/components/responses/Problem400" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/meals/{meal_id}/consumed": { "post": { "tags": [ "v1", "meals" ], "summary": "Mark a meal as consumed", "operationId": "markMealConsumed", "parameters": [ { "name": "meal_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Meal Id" } }, { "name": "consumed_date", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Consumed Date" } }, { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Meal-Output" } } } }, "400": { "$ref": "#/components/responses/Problem400" }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/shopping/current": { "get": { "tags": [ "v1", "shopping" ], "summary": "Get the current aggregated shopping list", "operationId": "getCurrentShoppingList", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CurrentShoppingList" } } } }, "422": { "$ref": "#/components/responses/Problem422" } } } }, "/api/v1/shopping/{list_id}": { "get": { "tags": [ "v1", "shopping" ], "summary": "Get a purchased shopping list by id", "operationId": "getShoppingList", "parameters": [ { "name": "list_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "List Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PurchasedShoppingList" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/shopping": { "post": { "tags": [ "v1", "shopping" ], "summary": "Purchase ingredients for a shopping list", "operationId": "purchaseIngredients", "parameters": [ { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ShoppingList" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PurchasedShoppingList" } } } }, "400": { "$ref": "#/components/responses/Problem400" }, "401": { "description": "Unauthorized (invalid or unknown user)", "content": { "application/problem+json": {}, "application/json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/shopping/current/me/ingredients": { "get": { "tags": [ "v1", "shopping" ], "summary": "Get my outstanding ingredient requests", "operationId": "getMyShoppingList", "parameters": [ { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Ingredient" }, "title": "Response Getmyshoppinglist" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] }, "post": { "tags": [ "v1", "shopping" ], "summary": "Sync my outstanding ingredient requests", "operationId": "syncMyShoppingList", "parameters": [ { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Ingredient" }, "title": "Requests" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Ingredient" }, "title": "Response Syncmyshoppinglist" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/shopping/current/meals/me": { "post": { "tags": [ "v1", "shopping" ], "summary": "Request a meal for shopping", "operationId": "requestMeal", "parameters": [ { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MealIdWrapper" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ShoppingListItem" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/shopping/current/meals/{meal_id}": { "delete": { "tags": [ "v1", "shopping" ], "summary": "Remove a meal request", "operationId": "unrequestMeal", "parameters": [ { "name": "meal_id", "in": "path", "required": true, "schema": { "type": "integer", "title": "Meal Id" } }, { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/api/v1/persons": { "get": { "tags": [ "v1", "persons" ], "summary": "List persons (paginated)", "operationId": "listPersons", "parameters": [ { "name": "q", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional case-insensitive name filter (applied after page read; may be pushed to SQL in the future).", "title": "Q" }, "description": "Optional case-insensitive name filter (applied after page read; may be pushed to SQL in the future)." }, { "name": "cursor", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "description": "Opaque cursor for pagination. Pass the value returned in nextCursor to fetch the next page.", "title": "Cursor" }, "description": "Opaque cursor for pagination. Pass the value returned in nextCursor to fetch the next page." }, { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "maximum": 200, "minimum": 1, "description": "Maximum number of items to return (1-200).", "default": 50, "title": "Limit" }, "description": "Maximum number of items to return (1-200)." } ], "responses": { "200": { "description": "A page of persons", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Page_Person_" }, "example": { "items": [ { "id": 1, "name": "Ada Lovelace" } ], "nextCursor": "2", "prevCursor": "0", "total": 1 } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "post": { "tags": [ "v1", "persons" ], "summary": "Create a person", "operationId": "createPerson", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Person" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Person" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/login": { "post": { "tags": [ "v1", "auth" ], "summary": "Login and set user_id cookie", "operationId": "login", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginBody" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Person" } } } }, "404": { "$ref": "#/components/responses/Problem404" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/refresh": { "post": { "tags": [ "v1", "auth" ], "summary": "Refresh current user from cookie", "operationId": "refresh", "parameters": [ { "name": "user_id", "in": "cookie", "required": true, "schema": { "type": "integer", "title": "User Id" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Person" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "cookieAuth": [] } ] } }, "/healthz": { "get": { "summary": "Healthz", "operationId": "healthz_healthz_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthStatus" } } } } } } } }, "components": { "schemas": { "CurrentShoppingList": { "properties": { "outstandingItems": { "items": { "$ref": "#/components/schemas/ShoppingListItem" }, "type": "array", "title": "Outstandingitems" }, "requestedMeals": { "items": { "$ref": "#/components/schemas/ShoppingListItem" }, "type": "array", "title": "Requestedmeals" }, "purchasedItems": { "items": { "$ref": "#/components/schemas/ShoppingListItem" }, "type": "array", "title": "Purchaseditems" }, "ingredientsLookup": { "additionalProperties": { "$ref": "#/components/schemas/Ingredient" }, "type": "object", "title": "Ingredientslookup" }, "mealsLookup": { "additionalProperties": { "$ref": "#/components/schemas/Meal-Output" }, "type": "object", "title": "Mealslookup" }, "shoppingListLookup": { "additionalProperties": { "$ref": "#/components/schemas/ShoppingList" }, "type": "object", "title": "Shoppinglistlookup" }, "recipesLookup": { "additionalProperties": { "$ref": "#/components/schemas/Recipe-Output" }, "type": "object", "title": "Recipeslookup" } }, "type": "object", "required": [ "outstandingItems", "requestedMeals" ], "title": "CurrentShoppingList" }, "HTTPValidationError": { "properties": { "detail": { "items": { "$ref": "#/components/schemas/ValidationError" }, "type": "array", "title": "Detail" } }, "type": "object", "title": "HTTPValidationError" }, "HealthStatus": { "properties": { "status": { "type": "string", "title": "Status", "default": "ok" } }, "type": "object", "title": "HealthStatus" }, "Ingredient": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "name": { "type": "string", "title": "Name" }, "line": { "type": "string", "title": "Line" }, "unit": { "type": "string", "enum": [ "Items", "Litre", "Gram", "Cup", "Tablespoon", "Teaspoon", "Ounce", "Pound", "Fluid Ounce", "Pint", "Quart", "Gallon", "Millilitre", "Milligram", "Kilogram" ], "title": "Unit", "description": "Measurement unit (enum values are advisory; runtime accepts any string)" }, "quantity": { "type": "number", "title": "Quantity" }, "preparation": { "type": "string", "title": "Preparation" }, "productId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Productid" }, "recipeId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Recipeid" }, "mealId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Mealid" }, "product": { "anyOf": [ { "$ref": "#/components/schemas/Product" }, { "type": "null" } ] } }, "type": "object", "required": [ "name", "line", "unit", "quantity", "preparation" ], "title": "Ingredient" }, "LoginBody": { "properties": { "username": { "type": "string", "title": "Username" } }, "type": "object", "required": [ "username" ], "title": "LoginBody" }, "Meal-Input": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "suggestedDate": { "type": "string", "format": "date-time", "title": "Suggesteddate" }, "consumedDate": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Consumeddate" }, "chefs": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Chefs" }, "cleanup": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Cleanup" }, "consumers": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Consumers" }, "recipes": { "items": { "$ref": "#/components/schemas/MealRecipe-Input" }, "type": "array", "title": "Recipes" }, "extraIngredients": { "items": { "$ref": "#/components/schemas/Ingredient" }, "type": "array", "title": "Extraingredients" }, "purchaseDate": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Purchasedate" } }, "type": "object", "required": [ "suggestedDate" ], "title": "Meal" }, "Meal-Output": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "suggestedDate": { "type": "string", "format": "date-time", "title": "Suggesteddate" }, "consumedDate": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Consumeddate" }, "chefs": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Chefs" }, "cleanup": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Cleanup" }, "consumers": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Consumers" }, "recipes": { "items": { "$ref": "#/components/schemas/MealRecipe-Output" }, "type": "array", "title": "Recipes" }, "extraIngredients": { "items": { "$ref": "#/components/schemas/Ingredient" }, "type": "array", "title": "Extraingredients" }, "purchaseDate": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Purchasedate" } }, "type": "object", "required": [ "suggestedDate" ], "title": "Meal" }, "MealIdWrapper": { "properties": { "mealId": { "type": "integer", "title": "Mealid" } }, "type": "object", "required": [ "mealId" ], "title": "MealIdWrapper" }, "MealRecipe-Input": { "properties": { "mealId": { "type": "integer", "title": "Mealid" }, "recipeId": { "type": "integer", "title": "Recipeid" }, "servings": { "type": "number", "title": "Servings" }, "recipe": { "anyOf": [ { "$ref": "#/components/schemas/Recipe-Input" }, { "type": "null" } ] } }, "type": "object", "required": [ "mealId", "recipeId", "servings" ], "title": "MealRecipe" }, "MealRecipe-Output": { "properties": { "mealId": { "type": "integer", "title": "Mealid" }, "recipeId": { "type": "integer", "title": "Recipeid" }, "servings": { "type": "number", "title": "Servings" }, "recipe": { "anyOf": [ { "$ref": "#/components/schemas/Recipe-Output" }, { "type": "null" } ] } }, "type": "object", "required": [ "mealId", "recipeId", "servings" ], "title": "MealRecipe" }, "Ok": { "properties": { "ok": { "type": "boolean", "title": "Ok", "default": true } }, "type": "object", "title": "Ok" }, "Page_Person_": { "properties": { "items": { "items": { "$ref": "#/components/schemas/Person" }, "type": "array", "title": "Items" }, "nextCursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Nextcursor" }, "prevCursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Prevcursor" }, "total": { "type": "integer", "title": "Total", "description": "Total count", "default": 0 } }, "type": "object", "required": [ "items" ], "title": "Page[Person]" }, "Page_Recipe_": { "properties": { "items": { "items": { "$ref": "#/components/schemas/Recipe-Output" }, "type": "array", "title": "Items" }, "nextCursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Nextcursor" }, "prevCursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Prevcursor" }, "total": { "type": "integer", "title": "Total", "description": "Total count", "default": 0 } }, "type": "object", "required": [ "items" ], "title": "Page[Recipe]" }, "Person": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "name": { "type": "string", "title": "Name" } }, "type": "object", "required": [ "name" ], "title": "Person" }, "ProblemDetails": { "properties": { "type": { "type": "string", "title": "Type", "default": "about:blank" }, "title": { "type": "string", "title": "Title" }, "status": { "type": "integer", "title": "Status" }, "detail": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Detail" }, "instance": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Instance" }, "errors": { "anyOf": [ { "type": "object" }, { "type": "null" } ], "title": "Errors" } }, "type": "object", "required": [ "title", "status" ], "title": "ProblemDetails" }, "Product": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "productId": { "type": "string", "title": "Productid" }, "shopCode": { "type": "string", "title": "Shopcode" }, "link": { "type": "string", "title": "Link" }, "name": { "type": "string", "title": "Name" }, "quantity": { "type": "integer", "title": "Quantity" }, "unit": { "type": "string", "title": "Unit" }, "imgSmall": { "type": "string", "title": "Imgsmall" }, "imgLarge": { "type": "string", "title": "Imglarge" } }, "type": "object", "required": [ "productId", "shopCode", "link", "name", "quantity", "unit", "imgSmall", "imgLarge" ], "title": "Product" }, "ProductUrl": { "properties": { "url": { "type": "string", "title": "Url" }, "tags": { "items": { "type": "string" }, "type": "array", "title": "Tags" } }, "type": "object", "required": [ "url" ], "title": "ProductUrl" }, "PurchasedShoppingList": { "properties": { "list": { "$ref": "#/components/schemas/ShoppingList" }, "mealsLookup": { "additionalProperties": { "$ref": "#/components/schemas/Meal-Output" }, "type": "object", "title": "Mealslookup" }, "ingredientsLookup": { "additionalProperties": { "$ref": "#/components/schemas/Ingredient" }, "type": "object", "title": "Ingredientslookup" }, "recipesLookup": { "additionalProperties": { "$ref": "#/components/schemas/Recipe-Output" }, "type": "object", "title": "Recipeslookup" } }, "type": "object", "required": [ "list" ], "title": "PurchasedShoppingList" }, "Recipe-Input": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "name": { "type": "string", "title": "Name" }, "link": { "type": "string", "title": "Link" }, "serves": { "type": "integer", "title": "Serves" }, "imageUrls": { "items": { "type": "string" }, "type": "array", "title": "Imageurls" }, "ingredients": { "items": { "$ref": "#/components/schemas/Ingredient" }, "type": "array", "title": "Ingredients" }, "basedOnRecipe": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Basedonrecipe" }, "dateCreated": { "type": "string", "format": "date-time", "title": "Datecreated" }, "createdById": { "type": "integer", "title": "Createdbyid" }, "createdBy": { "anyOf": [ { "$ref": "#/components/schemas/Person" }, { "type": "null" } ] }, "dateHidden": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Datehidden" }, "hiddenById": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Hiddenbyid" }, "hiddenBy": { "anyOf": [ { "$ref": "#/components/schemas/Person" }, { "type": "null" } ] } }, "type": "object", "required": [ "name", "link", "serves", "createdById" ], "title": "Recipe" }, "Recipe-Output": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "name": { "type": "string", "title": "Name" }, "link": { "type": "string", "title": "Link" }, "serves": { "type": "integer", "title": "Serves" }, "imageUrls": { "items": { "type": "string" }, "type": "array", "title": "Imageurls" }, "ingredients": { "items": { "$ref": "#/components/schemas/Ingredient" }, "type": "array", "title": "Ingredients" }, "basedOnRecipe": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Basedonrecipe" }, "dateCreated": { "type": "string", "format": "date-time", "title": "Datecreated" }, "createdById": { "type": "integer", "title": "Createdbyid" }, "createdBy": { "anyOf": [ { "$ref": "#/components/schemas/Person" }, { "type": "null" } ] }, "dateHidden": { "anyOf": [ { "type": "string", "format": "date-time" }, { "type": "null" } ], "title": "Datehidden" }, "hiddenById": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Hiddenbyid" }, "hiddenBy": { "anyOf": [ { "$ref": "#/components/schemas/Person" }, { "type": "null" } ] } }, "type": "object", "required": [ "name", "link", "serves", "createdById" ], "title": "Recipe" }, "ShoppingList": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "createdDate": { "type": "string", "format": "date-time", "title": "Createddate" }, "storeName": { "$ref": "#/components/schemas/StoreEnum", "default": "" }, "purchasedById": { "type": "integer", "title": "Purchasedbyid", "default": -1 }, "purchasedBy": { "anyOf": [ { "$ref": "#/components/schemas/Person" }, { "type": "null" } ] }, "items": { "items": { "$ref": "#/components/schemas/ShoppingListItem" }, "type": "array", "title": "Items" } }, "type": "object", "title": "ShoppingList" }, "ShoppingListItem": { "properties": { "id": { "type": "integer", "title": "Id", "default": -1 }, "listId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Listid" }, "personId": { "type": "integer", "title": "Personid", "default": -1 }, "ingredientId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Ingredientid" }, "recipeId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Recipeid" }, "mealId": { "anyOf": [ { "type": "integer" }, { "type": "null" } ], "title": "Mealid" }, "createdDate": { "type": "string", "format": "date-time", "title": "Createddate" } }, "type": "object", "title": "ShoppingListItem" }, "StoreEnum": { "type": "string", "enum": [ "woolworths", "coles", "" ], "title": "StoreEnum" }, "ValidationError": { "properties": { "loc": { "items": { "anyOf": [ { "type": "string" }, { "type": "integer" } ] }, "type": "array", "title": "Location" }, "msg": { "type": "string", "title": "Message" }, "type": { "type": "string", "title": "Error Type" } }, "type": "object", "required": [ "loc", "msg", "type" ], "title": "ValidationError" } }, "responses": { "Problem400": { "description": "Bad Request", "content": { "application/problem+json": {}, "application/json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "Problem404": { "description": "Not Found", "content": { "application/problem+json": {}, "application/json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "Problem422": { "description": "Validation Error", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } }, "application/json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } } }, "securitySchemes": { "cookieAuth": { "type": "apiKey", "in": "cookie", "name": "user_id", "description": "Authentication via user_id cookie (session-style)." } } } }