Problem / Motivation
Issue #458 specifies a 5-step "Create a piece & first state" onboarding tutorial but is
blocked on a TutorialOverlay shell component that was never built. The existing
SmallTutorialInlay infrastructure — declarative tutorials.yml, TutorialManager,
and dynamic backend serializer — is mature and already ships two production tutorials.
Implementing the same 5-step sequence on top of this unblocks first-user onboarding
without introducing a new overlay layer.
Proposed Solution
Add five create_piece_step_N entries to tutorials.yml, each attaching to the DOM
element that is present at that stage of the flow. To enforce strict step ordering
(so Step 2 never appears while Step 1 is still active), extend tutorials.yml and
TutorialManager.tsx with a depends_on field.
Tutorial steps
| Key |
Copy |
Attaches to |
Placement |
create_piece_step_1 |
"Start here — create your first piece." |
New Piece button |
right |
create_piece_step_2 |
"Give your piece a name." |
Name field in New Piece dialog |
right |
create_piece_step_3 |
"Advance to your first making step — wheel thrown or handbuilt." |
State transition chip group |
top |
create_piece_step_4 |
"Fill in the details as you work." |
Clay Body global entry field |
right |
create_piece_step_5 |
"You're tracking your first piece!" |
Piece name heading on detail page |
top |
Each step's action is dismiss-only — no dialog or navigation is triggered.
Step 5 has no action; clicking it dismisses it.
depends_on sequencing
Extend tutorials.schema.yml with an optional depends_on list of tutorial keys.
TutorialManager.tsx suppresses a tutorial unless every key in depends_on is
dismissed (preferences[key] === false). The chain:
create_piece_step_2 depends_on: [create_piece_step_1]
create_piece_step_3 depends_on: [create_piece_step_2]
create_piece_step_4 depends_on: [create_piece_step_3]
create_piece_step_5 depends_on: [create_piece_step_4]
DOM anchors
Add stable selectors (IDs or data-testid) to any element that lacks one:
- New Piece button in
PieceList.tsx
- Name input in
NewPieceDialog.tsx
- State transition chip group in
WorkflowState.tsx
- Clay Body
GlobalEntryField wrapper in WorkflowState.tsx
- Piece name/title heading in
PieceDetail.tsx
Backend
No backend changes required. The existing preferences.py dynamic serializer
automatically picks up the five new tutorial keys from tutorials.yml.
Acceptance Criteria
Out of Scope
- Building a
TutorialOverlay component.
- A "skip entire tutorial" affordance.
- Any "first login" API flag — default preference behavior (
true) is sufficient.
Supersedes #458.
Problem / Motivation
Issue #458 specifies a 5-step "Create a piece & first state" onboarding tutorial but is
blocked on a
TutorialOverlayshell component that was never built. The existingSmallTutorialInlayinfrastructure — declarativetutorials.yml,TutorialManager,and dynamic backend serializer — is mature and already ships two production tutorials.
Implementing the same 5-step sequence on top of this unblocks first-user onboarding
without introducing a new overlay layer.
Proposed Solution
Add five
create_piece_step_Nentries totutorials.yml, each attaching to the DOMelement that is present at that stage of the flow. To enforce strict step ordering
(so Step 2 never appears while Step 1 is still active), extend
tutorials.ymlandTutorialManager.tsxwith adepends_onfield.Tutorial steps
create_piece_step_1create_piece_step_2create_piece_step_3create_piece_step_4create_piece_step_5Each step's action is
dismiss-only— no dialog or navigation is triggered.Step 5 has no action; clicking it dismisses it.
depends_onsequencingExtend
tutorials.schema.ymlwith an optionaldepends_onlist of tutorial keys.TutorialManager.tsxsuppresses a tutorial unless every key independs_onisdismissed (
preferences[key] === false). The chain:create_piece_step_2depends_on:[create_piece_step_1]create_piece_step_3depends_on:[create_piece_step_2]create_piece_step_4depends_on:[create_piece_step_3]create_piece_step_5depends_on:[create_piece_step_4]DOM anchors
Add stable selectors (IDs or
data-testid) to any element that lacks one:PieceList.tsxNewPieceDialog.tsxWorkflowState.tsxGlobalEntryFieldwrapper inWorkflowState.tsxPieceDetail.tsxBackend
No backend changes required. The existing
preferences.pydynamic serializerautomatically picks up the five new tutorial keys from
tutorials.yml.Acceptance Criteria
tutorials.schema.ymlaccepts an optionaldepends_on: array of stringfield.TutorialManager.tsxhides a tutorial until alldepends_onkeys havepreferences[key] === false.tutorials.ymladds fivecreate_piece_step_Nentries with correct copy, selectors, placements, anddepends_onchains.data-testid); existing selectors are not changed.falseand makes the next step eligible to appear when its element enters the DOM.depends_onsuppression logic, each step's render/dismiss path, and step 2+ suppression while a prior step is still active.Out of Scope
TutorialOverlaycomponent.true) is sufficient.Supersedes #458.