timescale.info
Sign inSign up

How OpenChronology was built

Every merged pull request of openchronology/timeline-app, its first week of commits and its releases; and before them the 2020 PureScript editor, from snapshots of its deleted repositories in the Wayback Machine. Written to this server through the HTTP API.

327 moments · 2020-03-09T00:15:08Z CE – 2026-11-02T20:11:21Z CE · by @athan · @athan

#182 · Addresses: profiles at / , timelines at / / (#148)

  • timeline-app
  • pull request

Closes #148. Profiles are now at `/ ` and timelines at `/ / `, as on GitHub. A timeline without a slug is at `/ / `: its ID is a detail of it, and that is its address until its owner chooses a slug. ## How it works - **Routing:** the Next proxy resolves `/ / /…` to the timeline and rewrites it onto the existing `/timelines/ /…` pages, so every page under a timeline (history, pulls, settings, moments, durations, preview images) works at its address with no duplicated routes. - **Canonical address:** a page reached any other way (its ID, `/timelines/ `, a former slug, capitals) redirects to its own address, keeping the rest of the path and the query. - **Private timelines:** the redirect happens only after the page's access check, so an address reveals nothing of a private timeline to anyone who can't open it. - **Choosing a slug:** **Sharing & settings → Address**, which suggests one from the title (`The Fall of Rome (476)` → `the-fall-of-rome-476`). **Use its ID** removes it. - Rules: 1–64 lowercase letters, digits, `-` or `_`, starting with a letter or digit; not shaped like an ID. - Unique among its owner's timelines: a slug already taken is refused beside the field. - API: `PATCH /api/timelines/:id/settings {"slug": "…" | null}`. Setting only the slug leaves the timeline's revision unchanged, so open editors don't conflict. - **Former slugs:** a former slug keeps leading to its timeline until another of its owner's timelines takes it (`oc_timeline_former_slugs`). - **Reserved names:** names the site's own pages use, or may use (`login`, `admin`, `timelines`, `users`, `settings` and others: `RESERVED_NAMES` in `src/addresses.ts`), can't be registered. - An account that already has one, such as a first administrator named `admin`, keeps `/users/ ` and `/timelines/ `. - `/users/ ` otherwise redirects permanently to `/ `. - **Links using the new addresses:** lists, profiles, summaries, the sitemap, canonical links, oEmbed (which accepts any of a timeline's addresses), sign-in return paths, and the editor's address bar and share dialog. - Preview images and embeds stay at the ID. - **Desktop app:** it uses the new addresses only for servers whose replies include `slug`, so links to servers older than this change stay correct. ## Note on the proxy Next runs the proxy a second time on the rewritten request. The proxy marks the address it records with a per-process value, so the second pass leaves it alone. Without that, every page redirected to itself. ## Saving refreshes in place After a save, the platform page used to replace its address with `/timelines/ `. That was a same-address refresh until now; with this change it became a navigation that redirects, and it reloaded the editor mid-work. CI's save-merge live test caught it. The open timeline's page now refreshes in place, and a newly saved timeline's page still opens. ## Tests - `test/addresses.test.mjs` (new): the rules, reserved names, slugs suggested from titles, and how addresses parse. - Also extended: `links.test.mjs` (share paths), `next-route.test.mjs` (sign-in return paths). - `next-postgres.mjs`: - redirects from the old addresses and capitals; - invalid and taken slugs; - setting a slug leaves the revision unchanged; - a former slug redirects, then is freed for another timeline; - a private timeline is not found for guests at its address; - the moment page's canonical link, oEmbed and the sitemap; - removing the slug. - `sharing-postgres.mjs`: - pages at the new address; - in the browser, the Address setting suggests a slug, shows a taken slug's refusal beside the field, saves, and the settings page moves to the new address. - `account-security-postgres.mjs`: registration refuses a reserved name. - `accounts-browser.mjs`: the desktop sharing link for an owner with a reserved name. Locally, all of the following pass: - 275 unit tests, typecheck and Prettier; - the 44-test database suite; - the 11 browser suites; - `next-platform` and `next-postgres`. I also checke…

Sources

Open #182 · Addresses: profiles at / , timelines at / / (#148) in the timeline