███████╗██████╗ ██╗██╗ ██████╗
██╔════╝██╔══██╗██║██║ ██╔══██╗
███████╗██████╔╝██║██║ ██║ ██║
╚════██║██╔═══╝ ██║██║ ██║ ██║
███████║██║ ██║███████╗██████╔╝
╚══════╝╚═╝ ╚═╝╚══════╝╚═════╝
███████╗██████╗ ██████╗ ████████╗████████╗███████╗██████╗
██╔════╝██╔══██╗██╔═══██╗╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗
███████╗██████╔╝██║ ██║ ██║ ██║ █████╗ ██████╔╝
╚════██║██╔═══╝ ██║ ██║ ██║ ██║ ██╔══╝ ██╔══██╗
███████║██║ ╚██████╔╝ ██║ ██║ ███████╗██║ ██║
╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
AI-powered recipes to reduce food waste from Danish supermarkets (Netto, Bilka, Føtex). Browse clearance items at your local store, get recipe ideas from an AI chat assistant, or use the step-by-step recipe builder.
| Feature | Description |
|---|---|
| Chat Assistant | Ask about clearance items at your local store and get recipe ideas |
| AI Recipe Builder | Step-by-step wizard: pick a store, set preferences, get a tailored recipe |
| Category | Technology |
|---|---|
| Frontend | Next.js 16, shadcn/ui, Tailwind CSS |
| Backend | FastAPI (Python) |
| AI | Google Gemini |
| Data | dlt pipeline, DuckDB, Salling Group API |
| Deployment | Railway (Docker), GitHub Actions (scheduled refreshes) |
Caution
It is strongly recommended to use uv for managing the project.
After cloning the repository, create and activate a virtual environment:
uv venv
source .venv/bin/activateInstall dependencies:
uv syncCreate a .env file in the project root:
SALLING_FOOD_WASTE_SOURCE__ACCESS_TOKEN=your_salling_api_token
GOOGLE_SERVICE_ACCOUNT_KEY_BASE64=your_base64_key
GCP_PROJECT_NAME=your_project
GCP_PROJECT_LOCATION=europe-west1Get a Salling API token at https://developer.sallinggroup.com/
just pipeline # Run dlt data pipeline
just web-install # Install frontend + backend dependencies
just web-all # Start both frontend and backendFrontend: http://localhost:3000 | Backend: http://localhost:8000
just docker-build # Full build (~13 min, all zip codes)
just docker-build-test # Test build (~1 min, 20 zip codes)
just docker-run # Run container locally on :3000just pipeline # Run dlt data pipeline
just web # Start Next.js frontend
just web-backend # Start FastAPI backend
just web-all # Start both frontend and backend
just web-install # Install all dependencies
just docker-build # Build Docker image
just docker-build-test # Fast test build (20 zip codes)
just docker-run # Run Docker container
just clean # Clean generated files
The project uses Ruff for linting and formatting, and ty for type checking:
ruff format .
ruff check .
ty check .The project uses pre-commit hooks powered by Prek.
uv tool install prek
prek installRun hooks manually:
prek run -a├── salling_food_waste_pipeline.py # dlt pipeline (Salling API → DuckDB)
├── Dockerfile # Multi-stage Docker build
├── start.sh # Container startup script
├── web/
│ ├── src/
│ │ ├── app/ # Next.js pages & API routes
│ │ ├── components/ # React components (chat, recipe, ui)
│ │ ├── hooks/ # Custom hooks
│ │ └── lib/ # API client, utilities
│ └── backend/
│ └── main.py # FastAPI backend (Gemini AI, DuckDB queries)
├── sources/food_waste/ # DuckDB database
├── .github/workflows/ # Scheduled data refresh
├── .dlt/config.toml # dlt configuration
└── justfile # Task runner commands
The app is deployed on Railway as a single Docker service. A multi-stage Dockerfile fetches fresh clearance data at build time, builds the Next.js frontend, and bundles everything into a slim runtime image.
GitHub Actions triggers a redeploy twice daily (9am and 3pm CET) to refresh the data. Railway performs blue-green deploys for zero downtime.