feat: Guided Tours Ephemeral Pipelines#2334
Draft
camielvs wants to merge 1 commit into
Draft
Conversation
🎩 PreviewA preview build has been created at: |
Collaborator
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
3 tasks
ab7dd0b to
8eb1ea3
Compare
fb58c22 to
a71461e
Compare
151abae to
3b86f76
Compare
774e9d6 to
f3ba10d
Compare
802ddf3 to
fed719d
Compare
f3ba10d to
6f56eba
Compare
fed719d to
288fe40
Compare
6f56eba to
07be379
Compare
This was referenced May 28, 2026
e5bfdba to
a0f3b3d
Compare
444aa16 to
38b4021
Compare
a0f3b3d to
fc8f64e
Compare
38b4021 to
b2e2959
Compare
fc8f64e to
f42f1c1
Compare
63df8cc to
e33f721
Compare
e1c6d57 to
fc98693
Compare
e33f721 to
b4e258c
Compare
fc98693 to
f661d5c
Compare
9978c0a to
5d19fd6
Compare
3d52a59 to
bd097db
Compare
5d19fd6 to
297bd4c
Compare
bd097db to
84f39e0
Compare
297bd4c to
24ee700
Compare
24ee700 to
4c3e3c5
Compare
3 tasks
4c3e3c5 to
cc24888
Compare
24ed2d3 to
7f83eb8
Compare
cc24888 to
db99147
Compare
7f83eb8 to
9899ee2
Compare
9899ee2 to
a773cce
Compare
db99147 to
aa179eb
Compare
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.

Description
Moves tour pipelines out of the durable IndexedDB store and into session storage, so they are truly ephemeral. Before this change, a tour-pipeline lived alongside the user's real pipelines: it showed up in the pipelines list, contended for unique names, and survived browser refresh — none of which is what we want from a guided demo.
The fix is a scoped storage override that only applies while the user is on
/tour/$tourId. Inside the tour route,usePipelineStorage()returns aTourPipelineStorageServicebacked bysessionStorage; everywhere else, it still returns the durable IndexedDB service. The autosave path, the spec loader, and the editor's storage consumers don't need to know which one they're talking to.What changed
New scoped storage layer (
src/providers/TourProvider/tourPipelineStorage/)SessionStoragePipelineDriver.ts— driver that reads/writes pipeline YAML againstsessionStoragekeys, matching the shape the existingPipelineStorageServiceexpects from a driver.TourPipelineFolder.ts— single root folder that holds the tour pipeline, withcanMoveFilesOut: falseetc. so the rest of the app can't accidentally relocate it.TourPipelineStorageService.ts—PipelineStorageServicesubclass whoserootFolder,resolvePipelineByName, etc. all go through the session-storage driver.TourPipelineStorageProvider.tsx— context override that the tour route wraps its body in. Inside,usePipelineStorage()resolves to the tour service.resetAllTourPipelineState.ts— clears every__tour__*key from session storage and evicts matching entries from the react-query spec cache. Called when starting any tour so each run begins clean.Tour route plumbing (
src/routes/Dashboard/Learn/Tour.tsx)TourPageis split intoTourPage(resolves the tour, guards on!tour) andTourPageBody(does the pipeline resolution and rendering). The split exists soTourPipelineStorageProvidercan wrap the body —usePipelineStorage()insideTourPageBodythen resolves to the tour storage.createTourPipelineis renamedfindOrCreateTourPipelineto reflect that browser refresh mid-tour reuses the existing session-storage file (so the tour resumes on the same step with edits intact). Re-entering the tour from the Learn page still starts fresh —FeaturedTours/ToursLibrarycallresetAllTourPipelineStatebefore navigating, which wipes session storage and the react-query spec cache.Pipeline registry orphan fix (
src/services/pipelineService.ts)deletePipelineremoved the file from its folder driver but didn't delete the corresponding entry from the pipeline registry. The orphaned registry entry caused later "name already exists" errors for tour pipelines whose files had been cleared but whose registry rows lived on. Now both are deleted.Name-dialog race fix (
src/components/shared/Dialogs/PipelineNameDialog.tsx)setErroreffect that didn't always settle before the user clicked Submit, occasionally letting through a name that should have been rejected. Rewrote it as auseMemoso the error is always in sync with the current input. Also addedexcludeNamesso a rename-to-self in the regular editor doesn't flag itself as a collision.Why scoped override rather than a flag
Threading a
isTour: trueflag through every storage call would have leaked tour-awareness into a layer that doesn't need it. The provider override is opaque to consumers — sameusePipelineStorage(), samePipelineFileshape, different backing store.Related Issue and Pull requests
Progresses https://github.com/Shopify/oasis-frontend/issues/583
Type of Change
Checklist
Test Instructions
Pre-req: at least one registered tour exists (so use this branch with #2306 / #2312 on top, or open a Storybook-style local entry).
Ephemerality
?step=N) and the edit you made is still there (session storage survives same-tab refresh, as intended).Name-collision regression
/learn/tours. No "Name already exists" error —resetAllTourPipelineStateclears the prior run.Registry orphan regression
Regression