Skip to content

feat: add canonical station layouts#350

Open
duncanleo wants to merge 19 commits into
mainfrom
codex/station-layout-research-inventory
Open

feat: add canonical station layouts#350
duncanleo wants to merge 19 commits into
mainfrom
codex/station-layout-research-inventory

Conversation

@duncanleo

Copy link
Copy Markdown
Member

Summary

  • add 546 canonical station exits across 160 stations
  • add required lastUpdated provenance dates to station layout records
  • add current platform labels, line/service mappings, and standardized MRT door counts
  • cover all current MRT and LRT stations with 442 platform faces
  • add 153 platform-pair transfer paths across every current interchange
  • classify Bukit Panjang, Newton, and Tampines as out-of-station interchanges
  • retain the station-layout plan while removing temporary research scripts and staging artifacts

Why

Station records previously lacked complete passenger-facing layout data. This fills the canonical target layout directly in data/station so downstream consumers can render exits, boarding platforms, service directions, door counts, and interchange connectivity without relying on temporary research artifacts.

Data boundaries

  • MRT door counts use rolling-stock standards by line.
  • LRT door counts remain absent because one- and two-car formations coexist.
  • Transfer distances and traversal times remain null unless a defensible endpoint-to-endpoint measurement is available.
  • Door-relative escalator and lift anchors remain empty where official/operator public data does not support a reliable network-wide mapping.
  • Future station and future service changes are not modeled as current layout data.

Validation

  • npm run data:validate
  • npm run check
  • npm test — 30 files and 314 tests passed
  • coverage audit: no active station missing platforms, no empty platform service mappings, and no missing cross-line platform pair at current interchanges

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 191 files, which is 91 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: edf1c7a2-20c5-4d50-a388-b8335f14a94a

📥 Commits

Reviewing files that changed from the base of the PR and between ff1a07d and fc05bd4.

📒 Files selected for processing (191)
  • .changeset/closed-exits-update.md
  • data/station/ADM.json
  • data/station/ALJ.json
  • data/station/AMK.json
  • data/station/BAK.json
  • data/station/BBS.json
  • data/station/BBT.json
  • data/station/BCL.json
  • data/station/BDK.json
  • data/station/BDL.json
  • data/station/BDM.json
  • data/station/BDN.json
  • data/station/BDR.json
  • data/station/BFT.json
  • data/station/BGB.json
  • data/station/BGK.json
  • data/station/BGS.json
  • data/station/BKP.json
  • data/station/BKT.json
  • data/station/BLY.json
  • data/station/BNK.json
  • data/station/BNL.json
  • data/station/BNV.json
  • data/station/BRH.json
  • data/station/BSH.json
  • data/station/BSR.json
  • data/station/BTN.json
  • data/station/BTW.json
  • data/station/CBR.json
  • data/station/CCK.json
  • data/station/CDT.json
  • data/station/CGA.json
  • data/station/CGL.json
  • data/station/CLE.json
  • data/station/CNG.json
  • data/station/COM.json
  • data/station/COV.json
  • data/station/CPV.json
  • data/station/CRE.json
  • data/station/CRQ.json
  • data/station/CSW.json
  • data/station/CTH.json
  • data/station/CTM.json
  • data/station/CTN.json
  • data/station/DAM.json
  • data/station/DBG.json
  • data/station/DKT.json
  • data/station/DTN.json
  • data/station/DVR.json
  • data/station/EPN.json
  • data/station/EUN.json
  • data/station/FCN.json
  • data/station/FJR.json
  • data/station/FMW.json
  • data/station/FNV.json
  • data/station/FRP.json
  • data/station/FRR.json
  • data/station/GCL.json
  • data/station/GLB.json
  • data/station/GRB.json
  • data/station/GRW.json
  • data/station/HBF.json
  • data/station/HGN.json
  • data/station/HLV.json
  • data/station/HME.json
  • data/station/HPV.json
  • data/station/HVL.json
  • data/station/HVW.json
  • data/station/JKN.json
  • data/station/JLB.json
  • data/station/JLP.json
  • data/station/JUR.json
  • data/station/KAL.json
  • data/station/KAP.json
  • data/station/KDL.json
  • data/station/KEM.json
  • data/station/KGK.json
  • data/station/KKB.json
  • data/station/KPG.json
  • data/station/KPL.json
  • data/station/KRG.json
  • data/station/KRJ.json
  • data/station/KTB.json
  • data/station/KTH.json
  • data/station/KTP.json
  • data/station/KVN.json
  • data/station/LBD.json
  • data/station/LKS.json
  • data/station/LRC.json
  • data/station/LTI.json
  • data/station/LTR.json
  • data/station/LVR.json
  • data/station/LYR.json
  • data/station/MAX.json
  • data/station/MBT.json
  • data/station/MFL.json
  • data/station/MPR.json
  • data/station/MPS.json
  • data/station/MRB.json
  • data/station/MRD.json
  • data/station/MRM.json
  • data/station/MSL.json
  • data/station/MSP.json
  • data/station/MTC.json
  • data/station/MTR.json
  • data/station/NBG.json
  • data/station/NCH.json
  • data/station/NEW.json
  • data/station/NOV.json
  • data/station/NPR.json
  • data/station/OAS.json
  • data/station/OBV.json
  • data/station/ONH.json
  • data/station/ORC.json
  • data/station/OTP.json
  • data/station/PER.json
  • data/station/PGC.json
  • data/station/PGL.json
  • data/station/PGP.json
  • data/station/PMN.json
  • data/station/PND.json
  • data/station/PNR.json
  • data/station/PNX.json
  • data/station/PPJ.json
  • data/station/PSR.json
  • data/station/PTP.json
  • data/station/PTR.json
  • data/station/PYL.json
  • data/station/QUE.json
  • data/station/RCR.json
  • data/station/RDH.json
  • data/station/RFP.json
  • data/station/RIV.json
  • data/station/RMB.json
  • data/station/RNG.json
  • data/station/RNJ.json
  • data/station/SAV.json
  • data/station/SBW.json
  • data/station/SDM.json
  • data/station/SER.json
  • data/station/SGL.json
  • data/station/SGR.json
  • data/station/SHV.json
  • data/station/SHW.json
  • data/station/SIM.json
  • data/station/SKG.json
  • data/station/SMD.json
  • data/station/SMG.json
  • data/station/SMK.json
  • data/station/SNJ.json
  • data/station/SOM.json
  • data/station/SPL.json
  • data/station/STK.json
  • data/station/STV.json
  • data/station/TAM.json
  • data/station/TAP.json
  • data/station/TCR.json
  • data/station/TIB.json
  • data/station/TKG.json
  • data/station/TKK.json
  • data/station/TKL.json
  • data/station/TKT.json
  • data/station/TKW.json
  • data/station/TLA.json
  • data/station/TLB.json
  • data/station/TLK.json
  • data/station/TNG.json
  • data/station/TNM.json
  • data/station/TPE.json
  • data/station/TPG.json
  • data/station/TPW.json
  • data/station/TRH.json
  • data/station/TSG.json
  • data/station/TWR.json
  • data/station/UBI.json
  • data/station/UPC.json
  • data/station/UTS.json
  • data/station/WDL.json
  • data/station/WDN.json
  • data/station/WDS.json
  • data/station/WLH.json
  • data/station/XPO.json
  • data/station/YCK.json
  • data/station/YIS.json
  • data/station/YWT.json
  • docs/plans/active/station-layout-data.md
  • packages/core/src/schema/Station.test.ts
  • packages/core/src/schema/Station.ts
  • packages/fs/src/index.test.ts
  • packages/fs/src/validate.ts
  • scripts/generate-fixtures.mjs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Review on demand using usage pricing
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/station-layout-research-inventory

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@duncanleo
duncanleo marked this pull request as ready for review July 18, 2026 03:09

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ecc42e6e3d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/core/src/schema/Station.ts
Comment thread data/station/AMK.json
Comment thread data/station/CCK.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48f45e31c8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/MSP.json Outdated
Comment thread data/station/MRB.json Outdated
Comment thread packages/core/src/schema/Station.ts
Comment thread data/station/BSR.json Outdated
Comment thread data/station/XPO.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

"startedAt": "2035-12-31",

P2 Badge Add the known Tanah Merah exits

Tanah Merah's current station page lists public Exits 1 and 2 (for example, https://landtransportguru.net/tanah-merah-station/#Exits), but this new layout publishes exits: []. Because the schema has no unknown/not-collected state, clients will treat this as authoritative and hide every entrance or fail wayfinding for Tanah Merah even though open exits exist; add the known exits or avoid asserting an empty list.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/PER.json Outdated
Comment thread packages/core/src/schema/Station.ts Outdated
Comment thread data/station/PYL.json
Comment thread data/station/CCK.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

if (!serviceIncludesStation(service.value, station.value.id)) {

P2 Badge Validate platform services against current revisions

This new layout check only verifies that the service included the station in any revision, so a platform can advertise a service whose only matching stop was historical or future and still pass validation. Since the layout is documented as current-state data and platform serviceIds drive wayfinding, stale service mappings can validate cleanly after a service revision removes a station; check the current/open revision instead of any revision here.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/BKP.json Outdated
Comment thread data/station/BKP.json
Comment thread data/station/XPO.json
Comment thread data/station/MRB.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1efa17b4b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/CGA.json Outdated
Comment thread data/station/PER.json Outdated
Comment thread data/station/KPL.json Outdated
Comment thread data/station/CTM.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9e5031541

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/fs/src/validate.ts Outdated
Comment thread data/station/KPL.json
Comment thread data/station/AMK.json
Comment thread data/station/JUR.json
Comment thread data/station/CTN.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5572439eab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/TNM.json Outdated
Comment thread data/station/SNJ.json Outdated
Comment thread data/station/MPR.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ec08ad5b6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/KTP.json Outdated
Comment thread data/station/TKT.json Outdated
Comment thread data/station/MTC.json Outdated
Comment thread data/station/SGL.json Outdated
Comment thread data/station/BKT.json Outdated
Comment thread data/station/PTR.json Outdated
Comment thread data/station/SGR.json Outdated
Comment thread data/station/SHV.json Outdated
Comment thread data/station/TKW.json Outdated
Comment thread data/station/TRH.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6083574f9e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/TNM.json
Comment thread data/station/BGS.json
Comment thread data/station/CCK.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 119cc78f2b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/XPO.json
Comment thread data/station/DBG.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc05bd48db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread data/station/TNM.json
Comment on lines +155 to +157
"serviceIds": [
"EWL_CG_E"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Connect Platform A to advertised Platform E

When an airport-bound departure uses TNM_EWL_E—as this serviceIds mapping says it normally can—passengers arriving on the eastbound main line at Platform A have no corresponding direct transfer path: the layout contains A–D, F–D, and F–E, but not A–E. Consumers using these platform-pair paths can therefore route the same transfer when the branch train uses D but not when it uses E; add the A–E path or stop advertising E as a boarding platform for this service.

Useful? React with 👍 / 👎.

Comment on lines 203 to +205
Platforms represent public boarding areas. They should reference full scheduled
service patterns through `serviceIds`.
service patterns through `serviceIds`. A terminal platform used only to unload
arriving passengers remains part of the layout with `boardingStatus` set to

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document required layout update dates

lastUpdated is now required by StationLayoutLevelSchema, StationLayoutExitSchema, StationLayoutPlatformSchema, StationLayoutAccessPointSchema, and StationLayoutTransferPathSchema, but this active authoring plan's examples and field descriptions still omit it. Authors following the platform example here—or the level, exit, access-point, and transfer-path examples—will create records rejected by StationSchema, contrary to the repository review rule requiring documentation and code to agree; add the required field to each example and document its meaning.

Useful? React with 👍 / 👎.

from: {
kind: 'platform',
id: 'KET_ISL_E',
lastUpdated: '2026-07-18',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove update dates from transfer endpoints

StationLayoutTransferEndpointSchema and the newly documented contract define endpoint references as containing only kind and id, but the fixture generator now emits lastUpdated inside both endpoint objects. Zod silently strips these unsupported keys when repositories parse the fixture, so raw-fixture consumers and tests observe a shape that production repository consumers never receive; retain provenance on the transfer path and remove these two endpoint fields.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant