No description
  • Python 51.4%
  • TypeScript 47.4%
  • CSS 0.5%
  • JavaScript 0.3%
  • HTML 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jason Artemis Winstanley 74b7349241 Fix journey planner accepting overnight arrivals past latest_arrival
find_direct_journeys filtered latest_arrival by comparing the raw HHMM
arrival string, so an overnight service (e.g. departs 23:45, arrives
04:21 the next day) satisfied "arrive by 07:00" purely because 04:21
is numerically less than 07:00 - its real arrival is a calendar day
later than intended. Same gap existed in the two places
find_interchange_journeys/find_via_journey build a synthetic
cross-London transfer leg as an itinerary's final leg, which don't
route through find_direct_journeys' check at all.

Found while manually testing MKC->DWL via WAT with a tight arrival
window, which returned services arriving the following dawn; confirmed
the same wrong results also came from the plain non-via auto-search,
so this predates and is independent of the via-routing fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 17:26:25 +00:00
.impeccable Initial commit of Skyewatch 2026-07-28 19:58:59 +00:00
backend Fix journey planner accepting overnight arrivals past latest_arrival 2026-07-30 17:26:25 +00:00
frontend Add cross-London TfL interchanges to journey planner 2026-07-30 12:31:54 +00:00
raildata-sftp Initial commit of Skyewatch 2026-07-28 19:58:59 +00:00
.gitignore Initial commit of Skyewatch 2026-07-28 19:58:59 +00:00
CLAUDE.md Initial commit of Skyewatch 2026-07-28 19:58:59 +00:00
compose.yml Add SFTP upload folder for the RDM Routing Guide feed 2026-07-30 09:44:26 +00:00
DESIGN.md Initial commit of Skyewatch 2026-07-28 19:58:59 +00:00
PRODUCT.md Initial commit of Skyewatch 2026-07-28 19:58:59 +00:00
README.md Add README 2026-07-29 19:36:06 +00:00

Skyewatch

Skyewatch (aka Train Tracker) is a full-stack web app for monitoring UK railway services in real time. Add a train by headcode and see its live status, delays, current location, and per-stop calling points — glanceable enough to answer "is my train OK?" at a glance, with richer detail (timelines, delay history, disruption context) available for anyone who wants to dig in.

Features

  • Add trains by headcode, Service UID, or station departure board search — with live status, delay, current location, and platform.
  • Per-stop timelines showing booked vs. actual times all the way along a service's route.
  • Recurring trains for a regular commute, with bank-holiday-aware exceptions.
  • Journey planning — direct and interchange routes from the local timetable, with live delay data factored into whether a connection is actually catchable.
  • Notifications via Discord DM, Telegram, and Web Push — delays, cancellations, boarding/arrival, off-route alerts.
  • Punctuality stats and an archive of past journeys.
  • Household view — see other household members' trains for today.
  • Public share links for a single tracked train, no login required.
  • Disruption dashboard (TfL + National Rail), when configured.
  • Discord bot integration — slash commands, DM notifications, OAuth login.

Architecture

React 18 + Vite (nginx)
    ↕ HTTP/JSON
FastAPI + SQLAlchemy (Python 3.12)
    ↕ psycopg2
PostgreSQL 16

Live data comes primarily from a locally-ingested CIF full timetable feed (Rail Data Marketplace), overlaid with Darwin Push Port real-time movement events consumed continuously via Kafka — not the Realtime Trains (RTT) API, which is used only as a fallback when the local data has no match. See CLAUDE.md for the full data-pipeline design.

An MCP (Model Context Protocol) server is also exposed, so an AI assistant can look up live train status, search departures, plan journeys, and manage tracked trains on the user's behalf.

Running it

Requires Docker Compose. Copy .env.example (if present) or otherwise populate a .env file with the required credentials — see CLAUDE.md's Environment Variables section for the full list (database password, JWT secret, RTT/Darwin/NROD/Discord/Telegram/Web Push credentials, etc.).

docker compose up           # start the full stack (db, backend, frontend, raildata-sftp)
docker compose build        # rebuild images after a code change

The raildata-sftp service receives the daily CIF timetable push from Rail Data Marketplace; the backend watches for new files and ingests them automatically.

Frontend only

cd frontend
npm install
npm run dev      # Vite dev server, proxies /api → localhost:8000
npm run build    # TypeScript check + production build

Backend only

cd backend
alembic upgrade head
uvicorn app.main:app --host 0.0.0.0 --port 8000

Contributing / development notes

See CLAUDE.md for the full architecture write-up, data pipeline design, backend/frontend file structure, and the conventions this codebase follows (timezone handling, sync-vs-async DB access, JSON column mutation, etc.) — required reading before making non-trivial changes.