Troll-E is a location-aware grocery price comparison platform for New Zealand. It combines a FastAPI backend, scheduled scraping workers, and a React frontend to surface nearby deals across Countdown, PAK'nSAVE, and New World with trolley comparison and store ranking features.
- Architecture
- Data Flow
- Core Capabilities
- Getting Started
- Local Development
- API Overview
- Operations and Reliability
- Repository Layout
flowchart LR
subgraph Clients
WEB[Web App<br/>React + Vite]
end
subgraph Platform
API[FastAPI Service]
WORKER[Worker Scheduler]
DB[(PostgreSQL + PostGIS)]
REDIS[(Redis Cache)]
end
subgraph Sources
CHAINS[Retailer APIs<br/>Countdown / Foodstuffs]
end
WEB -->|HTTPS| API
API <--> DB
API <--> REDIS
WORKER -->|Ingest and Normalize| DB
WORKER -->|Scrape| CHAINS
flowchart TD
A[Retailer Source Data] --> B[Chain Scrapers]
B --> C[Normalization and Pricing]
C --> D[(PostgreSQL + PostGIS)]
D --> E[Search and Geospatial Services]
E --> F[Redis Cache]
E --> G[API Responses]
G --> H[Web Client]
- Aggregates product and price data from Countdown, PAK'nSAVE, and New World.
- Supports geospatial store and product discovery with configurable radius constraints.
- Provides trolley comparison to find the cheapest store for an entire shopping list.
- Suggests alternative products when items are unavailable at a given store.
- Ranks stores by category to surface the best deals nearby.
- Provides scheduled scraper execution via a dedicated worker service.
- Includes Redis-backed response caching for high-traffic queries.
- Ships with production-minded defaults: health checks, security headers, and rate limiting.
- Docker and Docker Compose
- Python 3.11+
- Node.js 18+ (for running frontend outside Docker)
- Poetry
cp .env.example .env
docker compose -f infra/docker-compose.yml up --buildServices started:
webathttp://localhost:5173apiathttp://localhost:8000db(PostgreSQL/PostGIS) onlocalhost:5432redisonlocalhost:6379workerfor scheduled ingestion
docker compose -f infra/docker-compose.prod.yml up -d --buildpoetry installdocker compose -f infra/docker-compose.yml up -d db redispoetry run uvicorn app.main:app --reload --app-dir apipoetry run python -m app.workers.runnercd web
npm install
npm run devcd api
python3 -m pytest app/tests/ -vInteractive API docs: http://localhost:8000/docs
Core endpoints:
GET /healthz- liveness probe.GET /health- dependency-aware health check (database + Redis).GET /readiness- readiness probe.GET /products- filtered and paginated product search.GET /products/{product_id}- product detail with all store prices.GET /stores- geospatial nearby stores.GET /stores/rankings- rank stores by category.POST /trolley/compare- compare cart cost across nearby stores.POST /trolley/suggestions- suggest alternatives for missing items.POST /auth/login- JWT token issuance.POST /auth/logout- token revocation.POST /ingest/run/{chain}- trigger ingestion (admin-protected).GET /worker/status- scraper status summary.
- Development environment template:
.env.example - Production compose file:
infra/docker-compose.prod.yml - Container definitions:
infra/dockerfiles/ - Nginx runtime config:
infra/nginx/ - Health checks are configured at both API and container levels.
- Security middleware adds standard hardening headers.
api/ FastAPI app, services, scrapers, worker, tests
web/ React + Vite frontend
infra/ Dockerfiles, Compose files, Nginx config