Metra Schedule Board Architecture
This site includes a live Metra schedule board focused on my regular UP-NW commute. It's intentionally built like a small production system — server-rendered, realtime-aware, commuter-focused, and designed to present the next trains that actually matter instead of sending visitors to a generic transit page.
Architecture Overview
- Frontend: Next.js App Router application
- API Layer: Server-side /api/metra/departures route (Node runtime)
- Static Data Layer: Metra GTFS static feed for routes, stops, trips, stop times, and service calendar
- Realtime Data Layer: Metra GTFS-realtime trip updates, vehicle positions, and alerts
- Normalization Logic: UP-NW filtering, stop-sequence direction detection, rider-friendly train number mapping, and arrival/departure shaping
- Source Control: GitLab (gitlab.com/daburritoking_project_group/personal-site)
- CI/CD & Hosting: Vercel (vercel.com/daburritoking-projects/personal-site)
CI/CD Pipeline
- Code is committed to GitLab and merged into main via standard Git workflows
- Vercel is connected directly to the GitLab repository
- Pushes to main trigger production deployments automatically
- Branches and merge requests generate preview deployments (when enabled)
- Build step runs dependency installation and next build before deploy
- Secrets for Metra feed access are stored in Vercel environment variables — never committed to source control
Request Flow
- User visits the Metra board page
- Browser sends a request to
/api/metra/departures - Server loads cached GTFS static data and fresh GTFS-realtime feeds
- UP-NW trips are filtered and direction is derived from stop sequence
- Trip IDs are translated into rider-facing train numbers
- Outbound trains are shaped as Ogilvie to Edison Park and inbound trains as Edison Park to Ogilvie
- Response is returned to the client and rendered as a live commuter board
Professional Enhancements
- The board is scoped to two real commuter flows instead of exposing the entire line schedule
- Outbound trains are presented as Ogilvie to Edison Park rather than by terminal destination, which is more useful for this commute
- Internal GTFS trip identifiers are translated into the train numbers riders actually recognize
- The page automatically uses current time so no date or schedule selection is required
- Service alerts are displayed directly on the page instead of requiring a separate trip to Metra's site
- The page uses the same visual language as the rest of the site so it feels integrated rather than bolted on
Security & Guardrails
Secrets Management
- Metra feed credentials never exposed to the browser
- Local development uses .env.local (ignored by Git)
- Production secrets stored securely in Vercel
- All feed access happens server-side only
Data Handling Controls
- Server-side filtering limits the response to the UP-NW route and two specific station flows
- Direction is based on stop-sequence logic rather than fragile text matching alone
- Safe error responses prevent upstream feed failures from leaking internal details
- Static GTFS and realtime GTFS are handled separately so live data stays fresh while expensive schedule parsing can be controlled
Operational Discipline
- The page is built as a focused utility rather than a generic redirect
- The API response is normalized into a commuter-friendly shape before it reaches the browser
- Changes are deployed through the same GitLab + Vercel workflow used by the rest of the site
Design Philosophy
Even a small personal feature like a train board benefits from production-style thinking: server-side secrets, explicit data flow, constrained scope, and a presentation layer shaped around what a user actually needs rather than around raw transit feed structure.
Roadmap
- Compact mobile-specific presentation for train rows
- Countdown-to-arrival indicators
- Better use of vehicle position data for richer live status language
- Performance improvements around static feed reuse and indexing
- Additional commute and transit-related utility pages