Publish each station route's canonical path - #208
Merged
Merged
Conversation
Consumers need the canonical URL for a station, and the database already decides it: routePath mints /<tides|currents>/<cc>/<sub>/<slug>/ and metadata/routes.lock.json records it. StationRoute exposes it as `path`, worked out at read time from the route's first station and its slug, so the database file is unchanged (no schema field, no bytes in the worker bundle). routePath lives once, in packages/database, and packages/stations loads it from source to mint the lock. A test reads every shipped route and requires its path to match the lock, so the read-time path cannot drift from the published one. Route building rejects a slug of two characters or fewer, since consumers read a two-letter first path segment as a country code. No current route has one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
commit: |
clarkbw
added a commit
to openwatersio/slackwater.xyz
that referenced
this pull request
Sep 27, 2026
A station's URL is the path the database publishes for its route, so /tides/us/pa/bridesburg/ sits under /tides/us/pa/, /tides/us/ and /tides/, and each of those is a browse page. The breadcrumb, sitemap and BreadcrumbList carry the same trail, so the place hierarchy a reader browses is the one search engines see in the URL. One splat route per kind resolves a path against the catalogue, because a subdivision and a station in an undivided country share a shape. The app's short share link still works: a bare slug 301s to the station's path, instant included. The AASA stops claiming browse and nested paths, which shipped app builds cannot parse, so those open in Safari. The redirect table goes: the site has no readers yet whose links need keeping. Pins openwatersio/slackwater-database#208's preview build until it is released. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 tasks
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
No unresolved review issues remain, and all reviewed changes are covered by tests and documentation.
Review effort: Lite
Findings: None
What changed in this PR
Adds canonical station route paths to database APIs, derived from station geography and slug without changing the existing schema.
Changes:
- Centralizes and exports route-path generation.
- Adds
pathtoStationRouteresults. - Validates short slugs and route-lock consistency.
- Documents and tests canonical paths.
| File | Summary |
|---|---|
packages/stations/test/route-builder.test.ts |
Tests short-slug rejection. |
packages/stations/routes.ts |
Reuses path generation and validates slugs. |
packages/database/test/routes.test.ts |
Tests route paths and lock consistency. |
packages/database/src/types.ts |
Adds path to StationRoute. |
packages/database/src/routes.ts |
Computes paths for decoded routes. |
packages/database/src/route-path.ts |
Defines canonical path generation. |
packages/database/src/index.ts |
Exports routePath. |
packages/database/README.md |
Documents canonical route paths. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Open
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
StationRoutefromstationRoutes()andstationRouteBySlug()has apath, the canonical station URL such as/tides/ca/bc/victoria/or/tides/us/pa/bridesburg/. openwatersio/slackwater.xyz uses it for its nested station URLs. Part of #174.The path is worked out when the route is read, from the route's first station (
country_code,region_code) and its slug. The schema and the.tcdbfile are unchanged, so older readers and the Swift package are unaffected, and the gzipped worker bundle is 136 bytes larger than on main (6,144,031 bytes).routePath()has one implementation, inpackages/database, exported from@slackwater/database.packages/stationsimports it from source to mintmetadata/routes.lock.json. The package entry can't be used there because it ships the database that@slackwater/databasebuilds by loadingpackages/stations.A test reads every shipped tide and current route and requires its
pathto equal the one the route lock records, so a read-time path can't drift from a published one.Route building rejects a slug of two characters or fewer, because consumers read a two-letter first path segment as a country code. No current route has one.
packages/databasetests (64) andpackages/stationstests (31,294)npm run build -w packages/database, including smokenpm run validate:databaseprettier --check .🤖 Generated with Claude Code