Skip to content

FE-1659: Give local Petrinaut documents UUID URLs and copy examples - #9661

Open
kube wants to merge 2 commits into
mainfrom
codex/fe-1659-local-document-urls
Open

FE-1659: Give local Petrinaut documents UUID URLs and copy examples#9661
kube wants to merge 2 commits into
mainfrom
codex/fe-1659-local-document-urls

Conversation

@kube

@kube kube commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Local demo documents open at /local/<UUID>, so bookmarks, reloads, and browser history reopen the selected file. Documents stay in the browser's local storage.

Published examples offer Make a local copy in the top bar. The copy opens at its own local URL with editing enabled.

Links

Changes

  • Assign persistent UUIDs to saved documents while preserving legacy storage keys and attached conversations
  • Give new, imported, and copied documents distinct UUIDs
  • Redirect / to the most recently edited document and /new to a new document
  • Keep empty documents when switching files so their URLs remain usable
  • Explain missing local documents and provide a link back to Petrinaut
  • Handle failed example-copy writes with an inline error
  • Update the user guide and website README, with a patch changeset for the guide bundled in @hashintel/petrinaut

Test coverage

  • Website suite: 463 tests passed, including UUID migration, duplicate repair, independent copies, direct routes, missing files, and Back/Forward navigation
  • Website build, type check, lint, repository formatting, and architecture check passed
  • Browser verification: copied a published example, edited its local copy, and reloaded the UUID URL
  • The Turbo execution graph is unchanged

How to test

  • Open /examples/sir-epidemic-model on the website preview
  • Choose Make a local copy and confirm the URL is /local/<UUID>
  • Rename the copy, move a place, and reload
  • Create another document from Menu > New, then use Back and Forward
  • Open /local/550e8400-e29b-41d4-a716-446655440000 in a browser without that file and confirm the recovery message

@kube kube self-assigned this Sep 11, 2026
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 11, 2026 2:51am UTC
petrinaut Ready Ready Preview Sep 11, 2026 2:51am UTC
petrinaut-docs Ready Ready Preview Sep 11, 2026 2:51am UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Sep 11, 2026 2:51am UTC

Request Review

@github-actions github-actions Bot added area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team area/apps labels Sep 11, 2026
@kube
kube added this pull request to stack #9663 September 11, 2026 02:41
@kube
kube marked this pull request as ready for review September 11, 2026 03:04
Copilot AI balanced review requested due to automatic review settings September 11, 2026 03:04
@cursor

cursor Bot commented Sep 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Routing and localStorage migration affect how every visitor opens and switches documents; behavior changes (no empty-net pruning, new / redirect) could surprise existing users but is covered by tests.

Overview
Local demo documents now open at stable /local/<UUID> URLs so bookmarks, reloads, and browser history target a specific file. / redirects to the most recently edited document (or creates one), and /new always creates a new empty document at its own URL. Switching nets no longer deletes untouched empty documents, so those links keep working.

Storage identity adds a persistent uuid on each saved net (new records use UUID as id), with readLocalStorageNets migrating legacy entries in place—repairing bad or duplicate UUIDs while keeping existing storage keys and AI conversation keys.

Published examples gain a top-bar Make a local copy action that saves a fork to localStorage and navigates to the new local URL; failed writes show an inline alert. Unknown UUIDs show a tailored not-found recovery page.

Docs (website README and drawing-a-net.md) and a patch changeset document the new URL and copy flows.

Reviewed by Cursor Bugbot for commit 1014585. Bugbot is set up for automated code reviews on this repo. Configure here.

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.

🟡 Changes recommended

The central editor-to-UUID navigation workflow lacks integration coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds persistent UUID routes for browser-local Petrinaut documents and enables editable copies of published examples.

Changes:

  • Adds UUID migration, creation, routing, and navigation.
  • Adds example copying and missing-document recovery.
  • Updates tests, documentation, and release metadata.
File summaries
File Description
.changeset/local-document-urls.md Adds the Petrinaut patch changeset.
apps/petrinaut-website/README.md Documents local UUID routes and copies.
apps/petrinaut-website/src/examples/full-example-page.tsx Adds the copy action and error alert.
apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx Connects document selection to routing.
apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts Adds UUID data to the fixture.
apps/petrinaut-website/src/main/app/local-storage-demo/use-local-storage-sdcpns.test.ts Tests UUID migration and copies.
apps/petrinaut-website/src/main/app/local-storage-demo/use-local-storage-sdcpns.ts Implements UUID persistence and migration.
apps/petrinaut-website/src/routes/-local.test.tsx Tests local routes and history.
apps/petrinaut-website/src/routes/-new.test.ts Tests distinct /new documents.
apps/petrinaut-website/src/routes/-not-found-page.tsx Supports customized recovery messages.
apps/petrinaut-website/src/routes/__root.tsx Adapts root not-found rendering.
apps/petrinaut-website/src/routes/examples.$slug.tsx Saves and opens example copies.
apps/petrinaut-website/src/routes/index.tsx Redirects home to the latest document.
apps/petrinaut-website/src/routes/local.$uuid.tsx Adds the local-document route.
apps/petrinaut-website/src/routes/new.tsx Redirects new documents to UUID URLs.
libs/@hashintel/petrinaut/docs/drawing-a-net.md Documents local URLs and example copies.
Review details
  • Files reviewed: 16/16 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +479 to +480
if (onNetChange) onNetChange(newNet);
else clearSharedLocation();

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1014585. Configure here.

setCurrentNetId(newNet.id);
clearSharedLocation();
if (onNetChange) onNetChange(newNet);
else clearSharedLocation();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New documents can 404 on navigate

Medium Severity

createNewNet adds the document through setStoredSDCPNs and then calls onNetChange, which navigates to /local/$uuid. That route's loader reads localStorage via readLocalStorageNets, not the hook. Mantine swallows setItem failures, so a quota or blocked-storage write still navigates and the loader throws not-found. /new and Make a local copy persist with saveLocalStorageNet before navigating, so those flows surface a save error instead of a missing-document page.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1014585. Configure here.

export const Route = createFileRoute("/")({
beforeLoad: ({ search }) => {
readLocalStorageNets(window.localStorage);
if (isCrewReservationFixtureSelected(search)) return;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is specific to Brunch fixture and should be flagged as something to remove soon.

We should not have (too much) spaghetti in the app.

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

Labels

area/apps area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants