chore: initial project setup with backend, frontend, and infrastructure
Some checks failed
CI / backend (push) Failing after 31s
CI / frontend (push) Successful in 40s
CI / docker (push) Has been skipped

Add complete NexaPantry application structure including:
- Docker Compose configuration with PostgreSQL, Redis, FastAPI backend, worker, frontend and Caddy
- Environment configuration template with database, auth, and service settings
- GitHub Actions CI workflow for backend/frontend linting, testing, auditing and Docker builds
- AGPL-3.0 license and comprehensive README with setup, development, and security documentation
- Backend
This commit is contained in:
2026-06-04 10:26:38 +02:00
commit 3792ca55e7
74 changed files with 13417 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
from app.models.entities import Product
RECIPES = [
{
"id": "tomato-pasta",
"name": {"de": "Tomaten-Pasta", "en": "Tomato pasta"},
"ingredients": ["tomato", "tomate", "pasta", "nudeln", "cheese", "käse"],
"steps": {"de": ["Nudeln kochen", "Tomaten anbraten", "Mit Käse servieren"], "en": ["Cook pasta", "Warm tomatoes", "Serve with cheese"]},
},
{
"id": "omelette",
"name": {"de": "Gemüse-Omelett", "en": "Vegetable omelette"},
"ingredients": ["egg", "ei", "cheese", "käse", "pepper", "paprika", "milk", "milch"],
"steps": {"de": ["Eier verquirlen", "Gemüse anbraten", "Stocken lassen"], "en": ["Whisk eggs", "Saute vegetables", "Let it set"]},
},
{
"id": "rice-bowl",
"name": {"de": "Reis-Bowl", "en": "Rice bowl"},
"ingredients": ["rice", "reis", "beans", "bohnen", "corn", "mais", "yogurt", "joghurt"],
"steps": {"de": ["Reis erhitzen", "Toppings ergänzen", "Mit Sauce servieren"], "en": ["Warm rice", "Add toppings", "Serve with sauce"]},
},
]
def suggest(products: list[Product], language: str) -> list[dict]:
names = " ".join([p.name.lower() for p in products])
expiring = {p.id for p in products if p.expires_at}
suggestions: list[dict] = []
for recipe in RECIPES:
matches = [i for i in recipe["ingredients"] if i in names]
if not matches:
continue
score = len(matches) + min(len(expiring), 3)
suggestions.append(
{
"id": recipe["id"],
"name": recipe["name"].get(language, recipe["name"]["en"]),
"matchedIngredients": sorted(set(matches)),
"score": score,
"steps": recipe["steps"].get(language, recipe["steps"]["en"]),
}
)
return sorted(suggestions, key=lambda item: item["score"], reverse=True)