Skip to content

kiliantscherny/spildspotter

Repository files navigation


                     ███████╗██████╗ ██╗██╗     ██████╗                         
                     ██╔════╝██╔══██╗██║██║     ██╔══██╗                        
                     ███████╗██████╔╝██║██║     ██║  ██║                        
                     ╚════██║██╔═══╝ ██║██║     ██║  ██║                        
                     ███████║██║     ██║███████╗██████╔╝                        
                     ╚══════╝╚═╝     ╚═╝╚══════╝╚═════╝                         
                                                                              
                     ███████╗██████╗  ██████╗ ████████╗████████╗███████╗██████╗ 
                     ██╔════╝██╔══██╗██╔═══██╗╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗
                     ███████╗██████╔╝██║   ██║   ██║      ██║   █████╗  ██████╔╝
                     ╚════██║██╔═══╝ ██║   ██║   ██║      ██║   ██╔══╝  ██╔══██╗
                     ███████║██║     ╚██████╔╝   ██║      ██║   ███████╗██║  ██║
                     ╚══════╝╚═╝      ╚═════╝    ╚═╝      ╚═╝   ╚══════╝╚═╝  ╚═╝
                                                                     

prek uv Ruff ty Next.js FastAPI DuckDB Railway Google Gemini
Deploy to Railway

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.

Features

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

Tech Stack

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)

Prerequisites

Caution

It is strongly recommended to use uv for managing the project.

  • Python >= 3.13
  • Node.js 22+
  • uv
  • just (optional, for task runner)

Installation

After cloning the repository, create and activate a virtual environment:

uv venv
source .venv/bin/activate

Install dependencies:

uv sync

Configuration

Create 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-west1

Get a Salling API token at https://developer.sallinggroup.com/

Usage

Local Development

just pipeline      # Run dlt data pipeline
just web-install   # Install frontend + backend dependencies
just web-all       # Start both frontend and backend

Frontend: http://localhost:3000 | Backend: http://localhost:8000

Docker

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 :3000

All Commands

just 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

Development

Code Quality

The project uses Ruff for linting and formatting, and ty for type checking:

ruff format .
ruff check .
ty check .

Pre-commit Hooks

The project uses pre-commit hooks powered by Prek.

uv tool install prek
prek install

Run hooks manually:

prek run -a

Project Structure

├── 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

Deployment

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.