Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4542eab
docs(status): record history and service-update design
CodeDotJS Oct 12, 2026
59ea1d3
feat(status): bake daily history and service update
CodeDotJS Oct 12, 2026
4382216
chore(status): add packed closure history
CodeDotJS Oct 12, 2026
4d28d33
chore(status): bake closures and service update
CodeDotJS Oct 12, 2026
67c7aee
chore(status): ship history in the bake workflow
CodeDotJS Oct 12, 2026
89a9a6f
feat(status): add service update pack fields
CodeDotJS Oct 12, 2026
b8a9fe3
feat(status): add history read and chart helpers
CodeDotJS Oct 12, 2026
bdaf250
test(status): cover history ranges and series
CodeDotJS Oct 12, 2026
a56ce3f
feat(status): load history and service update packs
CodeDotJS Oct 12, 2026
76017ba
test(status): cover service update pack loading
CodeDotJS Oct 12, 2026
556879a
feat(status): add history and service update copy
CodeDotJS Oct 12, 2026
df0d386
feat(status): add history chart and service update ui
CodeDotJS Oct 12, 2026
f8f4b7f
feat(status): wire history and service update into status
CodeDotJS Oct 12, 2026
db950b3
test(status): expect history chart and service update
CodeDotJS Oct 12, 2026
332ab08
feat(status): pass packed history into status view
CodeDotJS Oct 12, 2026
17f24b5
feat(status): style history chart dialog and service update
CodeDotJS Oct 12, 2026
fa7dd3b
docs(status): note history chart and bake schedule
CodeDotJS Oct 12, 2026
8bc36c6
docs(status): record history bake and schedule
CodeDotJS Oct 12, 2026
0f7a8ea
docs(status): document history and service-update bake
CodeDotJS Oct 12, 2026
9f48cbc
docs(status): mention status history in agents guide
CodeDotJS Oct 12, 2026
dc95b0c
docs(status): list status-history as shipped data
CodeDotJS Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/rules/50-local-files.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ These paths stay on this machine. They are listed in `.gitignore`. Do not delete
- `curls/` — saved request samples. Field notes are in `curls/STRUCTURE.md`. `docs/DMRC_API.md` records what those captures showed.
- `prompt.md` — original product brief. Shipped scope is in `docs/PRODUCT.md` and `AGENTS.md`.

Committed data the app reads: `data/manifest.json`, `data/en/line_list.json`, `data/en/stations/`, `data/en/station_brief/`, `data/en/coordinates.json`, `data/en/journeys/` once the pack has been built, `data/en/platforms.json`, which `python3 src/lib/offline/build_platforms.py` builds from that pack, and `data/en/status.json`, which `python3 src/lib/offline/build_status.py` packs from `metro_line` notes and linepage phrases. `tests/fixtures/dmrc/` stays too. Screen copy in `src/i18n/` is English only. Street tiles for the metro area are saved in `public/map-tiles/` by `python3 src/lib/offline/download_tiles.py`. Do not add zoom levels past 14, and do not download them from the service worker.
Committed data the app reads: `data/manifest.json`, `data/en/line_list.json`, `data/en/stations/`, `data/en/station_brief/`, `data/en/coordinates.json`, `data/en/journeys/` once the pack has been built, `data/en/platforms.json`, which `python3 src/lib/offline/build_platforms.py` builds from that pack, `data/en/status.json` and `data/en/status-history.json`, which `python3 src/lib/offline/build_status.py` packs from `metro_line` notes, linepage phrases, and the corporate service-update page. `tests/fixtures/dmrc/` stays too. Screen copy in `src/i18n/` is English only. Street tiles for the metro area are saved in `public/map-tiles/` by `python3 src/lib/offline/download_tiles.py`. Do not add zoom levels past 14, and do not download them from the service worker.
13 changes: 8 additions & 5 deletions .github/workflows/status.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Status

on:
# Asia/Kolkata wall times: 06:00, 14:00, 20:00. Cron is UTC (IST = UTC+5:30).
# Asia/Kolkata wall times: 08:00, 14:00, 20:00. Cron is UTC (IST = UTC+5:30).
schedule:
- cron: "30 0,8,14 * * *"
- cron: "30 2,8,14 * * *"
workflow_dispatch:

concurrency:
Expand Down Expand Up @@ -32,18 +32,20 @@ jobs:
echo "STATUS_BAKE_TOKEN is missing. Add a classic PAT with repo scope as that secret." >&2
exit 1
fi
if git diff --quiet -- data/en/status.json; then
if git diff --quiet -- data/en/status.json data/en/status-history.json; then
echo "status pack unchanged"
exit 0
fi
cp data/en/status.json /tmp/status.json
cp data/en/status-history.json /tmp/status-history.json
branch="chore/status-bake"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git fetch origin main
git checkout -B "$branch" origin/main
cp /tmp/status.json data/en/status.json
git add data/en/status.json
cp /tmp/status-history.json data/en/status-history.json
git add data/en/status.json data/en/status-history.json
if git diff --cached --quiet; then
echo "status pack unchanged on main"
exit 0
Expand All @@ -60,11 +62,12 @@ jobs:
--title "chore(status): bake station closures" \
--body "$(cat <<'EOF'
## Summary
- Refresh `data/en/status.json` from the DMRC bake
- Refresh `data/en/status.json` and `data/en/status-history.json` from the DMRC bake

## Test plan
- [ ] Status pack loads after merge
- [ ] Closed list matches the bake
- [ ] History chart reflects the day

EOF
)")
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ src/lib/status/ Closed-gate pack. Missing codes stay open.
src/lib/plan/ Plan state, saved trips, selection.
src/lib/play/ Play games. Questions are built only from saved data.
src/ui/ Screens. They consume transit types.
data/en/ English snapshot that ships: lines, stations, briefs, coordinates, journeys, platforms, status.
data/en/ English snapshot that ships: lines, stations, briefs, coordinates, journeys, platforms, status, status history.
public/map-tiles/ Street tiles for the metro area, through zoom 14.
```

Routes are calculated from station order. A packed journey supplies the fare, platform, and first and last train when that pair was saved. `python3 src/lib/offline/build_platforms.py` reads the packs and writes `data/en/platforms.json`, one boarding platform per station, line, and direction. `python3 src/lib/offline/build_status.py` writes `data/en/status.json` from live linepage phrases and metro_line notes. Closed gates cannot be boarded or left. Trains still pass. A transfer is allowed only when a note says the interchange facility is available. Plan still shows Least and Fewest for the asked pair, and Alternative via the one nearest open gate.
Routes are calculated from station order. A packed journey supplies the fare, platform, and first and last train when that pair was saved. `python3 src/lib/offline/build_platforms.py` reads the packs and writes `data/en/platforms.json`, one boarding platform per station, line, and direction. `python3 src/lib/offline/build_status.py` writes `data/en/status.json` from live linepage phrases, metro_line notes, and the corporate service-update page, and unions each day’s closed stations into `data/en/status-history.json`. Closed gates cannot be boarded or left. Trains still pass. A transfer is allowed only when a note says the interchange facility is available. Plan still shows Least and Fewest for the asked pair, and Alternative via the one nearest open gate.

## Constraints

Expand Down
220 changes: 220 additions & 0 deletions data/en/status-history.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"days": [
{
"count": 45,
"date": "2026-10-10",
"stations": [
{
"code": "AHRM",
"name": "ASHRAM"
},
{
"code": "AZU",
"name": "AZADPUR"
},
{
"code": "BIMR",
"name": "HAIDERPUR BADLI MOR"
},
{
"code": "BRKR",
"name": "BARAKHAMBA ROAD"
},
{
"code": "CTST",
"name": "CENTRAL SECRETARIAT"
},
{
"code": "CWBR",
"name": "CHAWRI BAZAR"
},
{
"code": "DLIG",
"name": "DELHI GATE"
},
{
"code": "GTBR",
"name": "GURU TEG BAHADUR NAGAR"
},
{
"code": "HKS",
"name": "HAUZ KHAS"
},
{
"code": "IDPT",
"name": "INDRAPRASTHA"
},
{
"code": "ILOK",
"name": "INDERLOK"
},
{
"code": "INA",
"name": "DILLI HAAT - INA"
},
{
"code": "ITO",
"name": "ITO"
},
{
"code": "JAMD",
"name": "JAMA MASJID"
},
{
"code": "JANR",
"name": "JAMIA MILLIA ISLAMIA"
},
{
"code": "JB",
"name": "JOR BAGH"
},
{
"code": "JFRB",
"name": "JAFRABAD"
},
{
"code": "JGPA",
"name": "JANGPURA"
},
{
"code": "JGPI",
"name": "JAHANGIRPURI"
},
{
"code": "JNPH",
"name": "JANPATH"
},
{
"code": "JW",
"name": "JHANDEWALAN"
},
{
"code": "KB",
"name": "KAROL BAGH"
},
{
"code": "KG",
"name": "KASHMERE GATE"
},
{
"code": "KJKS",
"name": "KHAJURI KHAS"
},
{
"code": "KM",
"name": "KHAN MARKET"
},
{
"code": "LJPN",
"name": "LAJPAT NAGAR"
},
{
"code": "LKM",
"name": "LOK KALYAN MARG"
},
{
"code": "MDHS",
"name": "MANDI HOUSE"
},
{
"code": "MKPR",
"name": "MAJLIS PARK"
},
{
"code": "MUPR",
"name": "MAUJPUR-BABARPUR"
},
{
"code": "NDI",
"name": "NEW DELHI (Yellow & Airport Line)"
},
{
"code": "NSHP",
"name": "NETAJI SUBHASH PLACE"
},
{
"code": "PTCK",
"name": "PATEL CHOWK"
},
{
"code": "PTMD",
"name": "SUPREME COURT"
},
{
"code": "RCK",
"name": "RAJIV CHOWK"
},
{
"code": "RI",
"name": "RITHALA"
},
{
"code": "RKAM",
"name": "RAMAKRISHNA ASHRAM MARG"
},
{
"code": "RP",
"name": "RAJENDRA PLACE"
},
{
"code": "SHD",
"name": "SHAHDARA"
},
{
"code": "SJSU",
"name": "SHIVAJI STADIUM"
},
{
"code": "SLAP",
"name": "SEELAMPUR"
},
{
"code": "UDB",
"name": "SEVA TEERTH (earlier UDYOG BHAWAN))"
},
{
"code": "VW",
"name": "VISHWAVIDYALAYA"
},
{
"code": "WC",
"name": "WELCOME"
},
{
"code": "YMVR",
"name": "YAMUNA VIHAR"
}
]
},
{
"count": 6,
"date": "2026-10-12",
"stations": [
{
"code": "BRKR",
"name": "BARAKHAMBA ROAD"
},
{
"code": "CTST",
"name": "CENTRAL SECRETARIAT"
},
{
"code": "JNPH",
"name": "JANPATH"
},
{
"code": "MDHS",
"name": "MANDI HOUSE"
},
{
"code": "PTCK",
"name": "PATEL CHOWK"
},
{
"code": "RCK",
"name": "RAJIV CHOWK"
}
]
}
]
}
74 changes: 72 additions & 2 deletions data/en/status.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,74 @@
{
"fetchedAt": "2026-10-12T00:06:41.000",
"stations": {}
"fetchedAt": "2026-10-12T08:10:01.000",
"serviceUpdate": {
"dated": "12.10.2026",
"fetchedAt": "2026-10-12T08:33:04.000",
"text": "New Delhi, Dated: 12.10.2026\nDue to security reasons, the entry and exit at the following metro stations will remain closed from 06:00 AM till 04:00 PM on 12th October, 2026. Further the situation will be reviewed by the security agencies and necessary updates will be shared accordingly. However, interchange facility will remain available at all the concerned metro stations.\n1. Patel Chowk\n2. Janpath\n3. Rajiv Chowk\n4. Mandi House\n5. Central Secretariat\n6. Barakhamba Road",
"title": "SERVICE UPDATE"
},
"stations": {
"BRKR": {
"end": "12-Oct-2026 06:00PM",
"lineCodes": [
"LN3"
],
"note": "Due to security reasons, Barakhambha Road metro Station is closed till further instructions.",
"phrase": "Station Closed",
"start": "12-Oct-2026 06:00AM",
"title": "Service Update"
},
"CTST": {
"end": "12-Oct-2026 06:00PM",
"lineCodes": [
"LN2",
"LN6"
],
"note": "Due to security reasons, Central Secretariat Metro Station is closed till further instructions.\r\n\r\nHowever, Interchange facility is available at Central Secretariat .",
"phrase": "Station Closed",
"start": "12-Oct-2026 06:00AM",
"title": "Service Update"
},
"JNPH": {
"end": "12-Oct-2026 06:00PM",
"lineCodes": [
"LN6"
],
"note": "Due to security reasons, Janpath metro Station is closed till further instructions.",
"phrase": "Station Closed",
"start": "12-Oct-2026 06:00AM",
"title": "Service Update"
},
"MDHS": {
"end": "12-Oct-2026 06:00PM",
"lineCodes": [
"LN3",
"LN6"
],
"note": "Due to security reasons, Mandi House Metro Station is closed till further instructions.\r\n\r\nHowever, Interchange facility is available at Mandi House .",
"phrase": "Station Closed",
"start": "12-Oct-2026 06:00AM",
"title": "Service Update"
},
"PTCK": {
"end": "12-Oct-2026 06:00PM",
"lineCodes": [
"LN2"
],
"note": "Due to security reasons, Patel Chowk Station is closed till further instructions.",
"phrase": "Station Closed",
"start": "12-Oct-2026 06:00AM",
"title": "Service Update"
},
"RCK": {
"end": "12-Oct-2026 06:00PM",
"lineCodes": [
"LN2",
"LN3"
],
"note": "Due to security reasons, Rajiv Chowk Metro Station is closed till further instructions.\r\n\r\nHowever, Interchange facility is available at Rajiv Chowk .",
"phrase": "Station Closed",
"start": "12-Oct-2026 06:00AM",
"title": "Service Update"
}
}
}
2 changes: 1 addition & 1 deletion docs/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The status bake collector is not the app. It may send the official `Origin` and

## Status

Closed gates are a showstopper. Status sits before Play. The pack is polled three times a day at 06:00, 14:00, and 20:00 Asia/Kolkata by GitHub Actions. A pull request opens only when the closed list changed, then merges through `check`. There is no R2, Worker, or Pages Function. Closed means no board and no alight. Trains still pass. Transfer is true only when a note says the interchange facility is available. A “will not be available” interchange note, or a silent closed station, blocks a change. Status names one nearest open station, not a list of gates. Plan keeps Least and Fewest for the asked pair and offers Alternative via that one open substitute. Location is requested only after “Use my location.” Coordinates are not stored.
Closed gates are a showstopper. Status sits before Play. The pack is polled three times a day at 08:00, 14:00, and 20:00 Asia/Kolkata by GitHub Actions. Each bake also unions that day’s closed stations into `data/en/status-history.json` and refreshes the corporate service-update notice when it changed. A pull request opens when `status.json` or `status-history.json` changed, then merges through `check`. There is no R2, Worker, or Pages Function. Closed means no board and no alight. Trains still pass. Transfer is true only when a note says the interchange facility is available. A “will not be available” interchange note, or a silent closed station, blocks a change. Status names one nearest open station, not a list of gates. Plan keeps Least and Fewest for the asked pair and offers Alternative via that one open substitute. Location is requested only after “Use my location.” Coordinates are not stored.

## No env file

Expand Down
2 changes: 1 addition & 1 deletion docs/DMRC_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ Live `GET /api/v2/en/metro_line/{code}` and `GET /api/v2/en/station_by_line_line

That day’s line_list rows were all `"Normal Service"`. Linepage station phrases were `"Station Open"` or `"Station Closed"`: 225 open rows, 61 closed rows, 45 unique station codes (an interchange is listed on each line). `stations_updates` is `""` on a quiet line and an array when there are notes. Notes attach by station code. Rajiv Chowk’s note says the interchange facility is available. New Delhi’s note says the interchange will not be available. A closed station with no interchange sentence is silent.

Gate-closed is not skip-station. The pack keeps closed stations only. A missing code is open. `python3 src/lib/offline/build_status.py` writes `data/en/status.json` only when the closed list changed. GitHub Actions polls three times a day at 06:00, 14:00, and 20:00 Asia/Kolkata. A failed bake keeps the previous file and clock.
Gate-closed is not skip-station. The pack keeps closed stations only. A missing code is open. `python3 src/lib/offline/build_status.py` writes `data/en/status.json` when the closed list or service-update notice changed, and merges that Asia/Kolkata day’s closed stations into `data/en/status-history.json` (union across bakes). It also fetches `GET /api/v2/en/corporate/service-update/` with the official `Origin` and `Referer` from `curls/service-status`. GitHub Actions polls three times a day at 08:00, 14:00, and 20:00 Asia/Kolkata. A failed bake keeps the previous files and clock.

## Integration limits

Expand Down
Loading
Loading