Skip to content

Publish each station route's canonical path - #208

Merged
clarkbw merged 1 commit into
mainfrom
route-path
Sep 27, 2026
Merged

clarkbw merged 1 commit into
mainfrom
route-path

Conversation

@clarkbw

@clarkbw clarkbw commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

StationRoute from stationRoutes() and stationRouteBySlug() has a path, 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 .tcdb file 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, in packages/database, exported from @slackwater/database. packages/stations imports it from source to mint metadata/routes.lock.json. The package entry can't be used there because it ships the database that @slackwater/database builds by loading packages/stations.

  • A test reads every shipped tide and current route and requires its path to 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/database tests (64) and packages/stations tests (31,294)

  • npm run build -w packages/database, including smoke

  • npm run validate:database

  • prettier --check .

🤖 Generated with Claude Code

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>
@pkg-pr-new

pkg-pr-new Bot commented Sep 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@slackwater/database@208

commit: e33ef50

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>
@clarkbw
clarkbw requested a lite review from Copilot September 27, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 path to StationRoute results.
  • 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.

@clarkbw
clarkbw merged commit 688c202 into main Sep 27, 2026
6 checks passed
@clarkbw
clarkbw deleted the route-path branch September 27, 2026 14:35
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.

2 participants