System design
Architecture
Two paths share one feature pipeline. Each quarter an offline refresh turns public data into a database and three trained models; on every page view the model service reads that database and runs the active model live.
Data flowShared code Core services
Offline: the quarterly refresh
- Download the state's quarterly price-list PDFs, NASA POWER weather and USDA crush reports.
- Parse the PDFs, identify wines, and extract region, brand, grape and classification from names.
- Link the same wine across quarters and name changes; each vintage is its own wine.
- Export training data with context tables and train three models using the shared wineprice package.
- Evaluate on held-out time periods, save a versioned artifact, and load its results into the database.
Online: every request
- The browser loads pages rendered by Next.js.
- Next.js calls the FastAPI model service for wines, prices, forecasts and model metrics.
- The service reads PostgreSQL and keeps the active model in memory.
- What-if requests re-run the model live on the wine's history with the changed price or promotion.
- A parity test checks that live predictions match the batch forecasts exactly.
How it maps to AWS
What runs where on AWS, chosen to keep running costs low (about $17 a month).
| Component | Status | How it runs |
|---|---|---|
| Website + model service | Live | One EC2 t4g.small (Ubuntu, arm64): nginx routes / to Next.js and /api/v1 to FastAPI |
| HTTPS and caching | Live | CloudFront in front; the server only accepts traffic from CloudFront, and has no SSH |
| Database | Live | PostgreSQL on the same instance, restored from a dump at each deploy; nightly backups to S3 |
| Infrastructure | Live | AWS CDK (Python): every deploy rebuilds the server from source, reproducibly |
| Cost guardrail | Live | AWS Budgets alerts at $5 and $20 a month |
| Quarterly training | Live | EventBridge Scheduler -> SSM Run Command on the server -> SageMaker Processing job (ml.t3.xlarge) trains all three models |
| Model registry | Live | Trained models are published to S3 (registry/<version>/) and hot-swapped by the API |
| Plain-English explanations | Live | Amazon Bedrock (Amazon Nova Lite), generated per wine on request, cached and rate-limited |
Details on the models themselves are on How it works.