mirror of
https://github.com/mblanke/Lottery-Tracker.git
synced 2026-03-01 06:00:21 -05:00
10 KiB
10 KiB
Lottery Tracker — Update Log
Overview
Complete codebase overhaul: cleanup, modernization, new features, and full Next.js frontend build.
Phase 1: Code Review & Cleanup
Files Deleted
email_sender.py— Email sending logic (removed entire email system)send_email_now.py— Manual email triggertest_email.py— Email testsanalyze_excel.py— Excel analysis utilityread_excel.py— Excel reader utilityimport requests.py— Misnamed utility scriptpowerball_numbers.html— Debug HTML filemegamillions_debug.html— Debug HTML fileDockerfile.email— Email service Docker imageEMAIL_SETUP.md— Email configuration docs
Issues Fixed
- Hardcoded credentials removed (Gmail password in docker docs)
verify=Falseon all HTTP requests replaced with default SSL verification- Code duplication — scraping logic was copy-pasted across 3 files, consolidated into one
- No tests — full test suite added
- No linting — ruff configured
- Flask
debug=Truehardcoded — replaced with env var - Docker healthcheck used
curl(not installed in slim image) — switched to Python urllib .dockerignoremissing.venv/— build context was 456 MB, now much smaller
Phase 2: Backend Rewrite
New Modules
config.py
AppConfigdataclass with nestedScraperURLs,TaxConfig,InvestmentDefaultsSTATE_TAX_RATES— all 51 US states + DC with 2024-2025 tax ratesLOTTERY_ODDS— odds and ticket costs for all 4 lotteriesANNUITY_YEARS,ANNUITY_ANNUAL_INCREASEconstantsload_config()reads from environment variables with sensible defaults
scrapers.py
- Unified scraping with TTL cache (6-hour default via
cachetools) scrape_powerball()/scrape_mega_millions()— requests + BeautifulSoup from lotto.netscrape_canadian_lotteries()— Playwright sync API from olg.caget_all_jackpots()— returns all 4 jackpots with cacheclear_cache()— force refresh
app.py (Rewritten)
Flask app factory pattern (create_app()) with endpoints:
| Endpoint | Method | Description |
|---|---|---|
/api/jackpots |
GET | Current jackpots (cached) |
/api/jackpots/refresh |
POST | Force-refresh jackpots |
/api/calculate |
POST | Full investment calculation with state tax |
/api/states |
GET | All US states with tax rates |
/api/states/<code> |
GET | Single state info |
/api/compare |
GET | Side-by-side all 4 lotteries |
/api/calculate/breakeven |
POST | Break-even jackpot analysis |
/api/calculate/annuity |
POST | Annuity payment schedule |
/api/calculate/group |
POST | Group play split |
/api/odds |
GET | Probability data for all lotteries |
/api/health |
GET | Health check |
lottery_calculator.py (Rewritten)
Pure calculation functions with explicit parameters:
_run_investment_cycles()— shared 90-day reinvestment cycle logiccalculate_us_lottery()— lump sum + federal/state tax + CAD conversion + cyclescalculate_canadian_lottery()— tax-free + investment cyclescalculate_break_even()— EV formula: required jackpot for positive expected valuecalculate_annuity()— 30-year schedule with configurable annual increasecalculate_group_split()— N-way split with custom share ratios
Configuration Files
requirements.txt— pinned versions, removed openpyxl/pandas/schedulerequirements-dev.txt— pytest, pytest-mock, pytest-cov, httpx, ruffpyproject.toml— ruff config (line-length=100, py311 target), pytest config.env.example— all environment variables documented
Test Suite (64 tests, all passing)
tests/conftest.py— Flask test fixturestests/test_lottery_calculator.py— ~25 tests (US calc, Canadian calc, break-even, annuity, group split)tests/test_api.py— ~15 endpoint integration tests with mocked scraperstests/test_config.py— config loading, env override, state validationtests/test_scrapers.py— parser tests, mocked HTTP, cache behavior
Phase 3: Frontend (Next.js 15 + MUI 6)
Scaffold
frontend/package.json— Next.js 15.1.4, MUI 6.3.1, Recharts 2.15, Axiosfrontend/tsconfig.json— standard Next.js TypeScript config with@/*pathsfrontend/next.config.js— standalone output,/api/*rewrite to backendfrontend/.env.local—NEXT_PUBLIC_API_URL=http://localhost:5000
Shared Libraries
frontend/lib/types.ts— Full TypeScript interfaces (JackpotData, Calculation, StateInfo, BreakEvenResult, AnnuityResult, GroupResult, OddsInfo, etc.)frontend/lib/api.ts— Typed Axios client with all API endpoint functionsfrontend/lib/format.ts—formatCurrency,formatCurrencyFull,formatPercent,formatNumberfrontend/lib/theme.ts— Dark MUI theme (primary:#4fc3f7, background:#0a1929)
Components
frontend/components/ThemeRegistry.tsx— MUI ThemeProvider wrapper with CssBaselinefrontend/components/NavBar.tsx— Sticky app bar with navigation links
Pages (7 routes)
| Route | File | Description |
|---|---|---|
/ |
app/page.tsx |
Home — jackpot cards grid (4 lotteries) + tool cards grid (6 tools) |
/calculator |
app/calculator/page.tsx |
Investment calculator — jackpot input, lottery type, state selector with tax rates, invest % slider, annual return slider, cycles, results summary, 90-day cycle table |
/compare |
app/compare/page.tsx |
Side-by-side comparison — state selector, 4 lottery cards with jackpot, odds, after-tax take-home, daily/annual income |
/breakeven |
app/breakeven/page.tsx |
Break-even analysis — lottery/state selectors, required jackpot, odds, probability, take-home fraction, expected value |
/annuity |
app/annuity/page.tsx |
Annuity calculator — jackpot, type, years, annual increase slider, summary cards, year-by-year payment schedule table |
/group |
app/group/page.tsx |
Group play — member count, custom share weights, per-member breakdown table (share %, jackpot share, after-tax, daily/annual income) |
/odds |
app/odds/page.tsx |
Probability display — odds, percentage, ticket cost, log-scale relative bar, "50% chance" ticket count |
Phase 4: Docker & Infrastructure
Docker Images Built
| Image | Size | Description |
|---|---|---|
lottery-tracker-backend |
2.28 GB | Python 3.13-slim + Playwright Chromium + Gunicorn |
lottery-tracker-frontend |
285 MB | Node.js 20-alpine + Next.js standalone |
Docker Fixes Applied
- Removed
playwright install-deps chromiumfrom Dockerfile.backend — system deps already installed manually; the auto-installer fails on newer Debian due to renamed font packages (ttf-unifont→fonts-unifont) - Generated
package-lock.json— required bynpm ciin frontend Dockerfile - Created
frontend/public/directory withmanifest.json— Dockerfile COPY step requires it - Added
.venv/to.dockerignore— was inflating build context - Removed
version: '3.8'warning — obsolete in modern Docker Compose - Removed email-scheduler service from
docker-compose.yml - Switched healthcheck from
curltopython -c "import urllib.request; ..." - Backend CMD changed to gunicorn (2 workers, 120s timeout)
MUI Grid Fix
All 7 frontend pages used <Grid size={{ xs: 12, sm: 6 }}> syntax (Grid2 API), but imported Grid from @mui/material (legacy Grid v1). Fixed by changing imports to Grid2 as Grid in all pages.
Running Containers
| Container | Status | Port Mapping |
|---|---|---|
lottery-backend |
Up (healthy) | 0.0.0.0:5000 → 5000 |
lottery-frontend |
Up | 0.0.0.0:3003 → 3000 |
Access URLs
- Frontend: http://localhost:3003
- Backend API: http://localhost:5000/api/health
Phase 5: Documentation & Config
Updated Files
.gitignore— added.next/,*.xlsx,*.html,ssl/certs, coverage outputsAGENTS.md— filled in repo facts (Python 3.13/Flask + Next.js 15/MUI 6, pytest, ruff, docker compose)DOCKER_README.md— rewritten: removed email references, removed hardcoded password, added.env.exampleworkflow, config table, production deployment guideDOCKER_QUICKSTART.md— rewritten: removed email service, updated container descriptions, simplified quick start
Verification
- 64/64 tests passing (
pytest -q) - ruff lint clean (
ruff check .— all checks passed) - Docker build successful — both images built
- Containers running — backend healthy, frontend serving
Architecture Summary
┌─────────────────────────────────────────────────┐
│ nginx (prod) │
│ Rate limiting + SSL │
├─────────────────┬───────────────────────────────┤
│ Frontend │ Backend │
│ Next.js 15 │ Flask 3.1 │
│ MUI 6 │ Gunicorn │
│ TypeScript │ Python 3.13 │
│ Port 3000 │ Port 5000 │
│ │ │
│ 7 pages │ 11 API endpoints │
│ Dark theme │ 4 lottery scrapers │
│ Axios client │ TTL cache (6h) │
│ │ 51 state tax rates │
│ │ Playwright (Canadian) │
└─────────────────┴───────────────────────────────┘
Tech Stack
- Backend: Python 3.13, Flask 3.1, Gunicorn, BeautifulSoup, Playwright
- Frontend: Next.js 15, TypeScript, Material-UI 6, Recharts, Axios
- Testing: pytest (64 tests), ruff (lint)
- Docker: Multi-container (backend + frontend + nginx for prod)
- Config: Environment variables via
.env+python-dotenv