2.6 KiB
2.6 KiB
PDGA Rating Tracker
PDGA rating scraper and display app. Scrapes player ratings and course data from pdga.com, stores in SQLite, serves via Express with EJS templates and HTMX.
Tech Stack
- Runtime: Node.js 18 (Alpine in Docker)
- Server: Express with EJS templates
- Database: SQLite3 (file:
ratings.db, Docker:/app/data/ratings.db) - Frontend: HTMX + vanilla JS (in
public/js/) - Scraping: Puppeteer (with stealth plugin) + direct HTTP
- Logging: Pino (JSON in production, pino-pretty in dev)
- CI/CD: Release Please + Docker build/push to GHCR
Project Structure
server.js # Express app entrypoint
src/
logger.js # Pino logger instance
db.js # SQLite init, migrations, seeding
models/ # Data access (player.js, course.js)
routes/ # Express routes (players, courses, pages)
scrapers/ # PDGA scrapers (HTTP + Puppeteer)
services/ # Business logic (player-service, rating-calculator)
views/
pages/ # EJS page templates
partials/ # EJS partials (shared layout)
public/
css/ # Stylesheets
js/ # Client-side JS (HTMX interactions)
Commands
npm start— Start production server (port 3000)npm run dev— Start with nodemon (auto-reload)LOG_LEVEL=debug npm start— Enable debug loggingdocker compose up— Run via Docker
Conventions
- Logging: Use
require('./logger')(or relative path). Never useconsole.log/errorin backend code. Use appropriate Pino levels:debugfor verbose/diagnostic data,infofor operational status,warnfor retries/degraded state,errorfor failures,fatalfor startup crashes. - Frontend JS:
console.erroris fine inpublic/js/— runs in browser, no Pino. - Commits: Conventional commits (
feat:,fix:,refactor:,chore:) — drives release-please. - Scraping: Two strategies per entity: direct HTTP (fast, preferred) with Puppeteer fallback (stealth plugin for anti-bot). Rate limiting must be respected.
- Database: Migrations run automatically on startup in
db.js. Schema changes go there. - Templates: EJS with shared layout in
views/partials/. Pages use HTMX for dynamic content loading.
Environment Variables
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
info |
Pino log level |
NODE_ENV |
— | Set to production for JSON logs |
DB_PATH |
./ratings.db |
SQLite database path |
PUPPETEER_EXECUTABLE_PATH |
— | Chromium path (set in Docker) |