Serverless AWS pipeline tracking and predicting South African fuel price adjustments- built with Terraform, Lambda, and event-driven architecture.
# Fuel Price Tracker South Africa
A cloud-native AWS application that turns the Central Energy Fund's daily fuel-price recovery reports into a transparent estimate of South Africa's next petrol, diesel, and illuminating-paraffin adjustment.
The project is intentionally infrastructure-forward: scheduled ingestion, pre-computed predictions, public APIs, private static hosting, DNS/TLS, monitoring, and deployment are all defined in Terraform rather than hidden behind a managed frontend platform.
> **Forecasts are estimates, not official announcements.** The Department of Mineral and Petroleum Resources remains the authoritative source for regulated price changes. Statutory levy or margin changes can cause the official adjustment to differ from the Basic Fuel Price recovery signal.
## What is implemented
- Daily EventBridge schedule discovers the latest CEF Daily Basic Fuel Price PDF.
- Python ingestion Lambda validates the PDF, normalises parenthesised under-recoveries to negative cents/litre, and idempotently writes all five products.
- DynamoDB keeps daily observations and immutable prediction snapshots.
- Python/pandas prediction Lambda produces a direction, range, and confidence score after ingestion.
- TypeScript Lambda exposes a small cacheable HTTP API through API Gateway.
- Responsive React dashboard is deployed to a private S3 bucket and served only through CloudFront.
- Route 53, ACM HTTPS certificates, CloudWatch logs/dashboard/alarms, and SNS operational email are Terraform-managed.
- GitHub Actions tests and plans pull requests, then applies and deploys `main` using short-lived AWS OIDC credentials.
Public price-change subscriptions are a stretch goal; SNS is currently used for operator alerts when ingestion or prediction fails.
## Architecture
```mermaid
flowchart LR
CEF["CEF daily report page + PDF"] -->|"HTTPS daily"| ING["Python ingestion Lambda"]
EB["EventBridge schedules"] --> ING
EB --> PRED["Python prediction Lambda"]
ING --> REC[("DynamoDB …