CI surfaced react-hooks/set-state-in-effect on the synchronous setState(computeState(token)) inside the useEffect body. The earlier shape mirrored token -> state via an effect, which is exactly the "you might not need an effect" pattern React 19's eslint rule now flags. Switch to derived state: compute during render, use a useReducer tick to force re-render on the 30s cadence (so relative timestamps stay current even when token props don't change). Same observable behavior, no cascading renders. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.6 KiB
7.6 KiB
Plan: Flexible Intake — Deferred Variables + Prepared Sessions
Context
The current intake form on procedural flows is a blocking modal that forces engineers to enter all variables before the flow starts. This creates friction because:
- Engineers don't always have all the information upfront
- Information often lives in PSA tickets, RMM tools, or was communicated verbally
- Sometimes a lead/PM has the info and wants to set up the session for an engineer to execute later
Goal: Replace the blocking intake modal with two complementary workflows:
- Deferred Variables — start the flow immediately, fill variables inline as you encounter them
- Prepared Sessions — pre-fill variables ahead of time, optionally assign to an engineer, execute later
Design
Workflow 1: Deferred Variables (Start Now, Fill Later)
- "Start Flow" launches the session immediately — no intake modal
- Variables begin empty
- When a step references
[VAR:server_name]and it's unfilled, an inline input prompt renders in place — visually prominent with the field's label, help text, and styling that stands out (cyan border, slight glow) - Once filled, the value persists and resolves everywhere in the session
- Engineers can also open a "Session Variables" side panel at any time to see/edit all variables
- At session completion, if required variables are still empty → soft warning with a prompt to fill them (for complete export documentation), but not a hard block
Workflow 2: Prepared Sessions (Set Up Ahead, Execute Later)
- From a flow's detail page: "Prepare Session" action opens a form to fill variables + assign an engineer
- Creates a session in
preparedstate —started_atis null, variables populated, no steps executed - Assignment: Preparer can assign to a specific engineer on their team (or leave unassigned)
- Personal queue: Engineers see prepared sessions assigned to them in a dedicated section (Quick Start page or Session History tab)
- Clicking a prepared session opens the flow with variables pre-populated; execution begins normally
- Unassigned prepared sessions are visible to all team members
Data Model Changes
Session model additions:
prepared_by_id— UUID FK to users, nullable. Who created the prepared session.assigned_to_id— UUID FK to users, nullable. Who should execute it.- Use existing convention:
started_at IS NULL= prepared,started_at IS NOT NULL, completed_at IS NULL= active,completed_at IS NOT NULL= completed
Session variables become mutable:
session_variablesis currently write-once at session creation- New endpoint:
PATCH /sessions/{id}/variables— updates individual variables during an active session - Only the session owner (or assigned engineer) can update variables
Migration: One migration adding prepared_by_id and assigned_to_id columns with FK constraints.
Variable Resolution Changes
Backend:
- No changes to export pipeline — it already resolves variables from
session_variables - New
PATCH /sessions/{id}/variablesendpoint accepts partial variable updates - Session creation no longer validates required intake fields (they can be filled later)
Frontend — resolveVariables() in lib/variableResolver.ts:
- Currently returns a plain string with
[VAR:x]replaced - New behavior: also identify unresolved variables so
StepDetailcan render inline prompts
Frontend — StepDetail.tsx:
- When rendering step content, unresolved
[VAR:x]references render as inline input components - Inline prompt design: input field with the field's label as placeholder, cyan border, subtle glow background to make them visually prominent and easy to spot
- On blur/enter: calls
PATCH /sessions/{id}/variables→ re-renders step with resolved value - Lookup field metadata (label, field_type, help_text, options) from the intake form definition in the tree snapshot
Frontend — Session Variables Panel:
- Existing "View Parameters" button becomes "Session Variables" — now editable
- Shows all intake form fields with filled/unfilled status
- Unfilled required fields highlighted
- Editing a field here updates the session and re-resolves all visible steps
API Changes
| Method | Endpoint | Description |
|---|---|---|
PATCH |
/sessions/{id}/variables |
Update one or more session variables (partial dict merge) |
POST |
/sessions |
Remove required-field validation for intake forms (allow empty start) |
GET |
/sessions |
Add assigned_to_id and status=prepared filter params |
POST |
/sessions/prepare |
New endpoint: create a prepared session with variables + optional assignee |
UI Changes
| Location | Change |
|---|---|
| Flow detail page | "Start Flow" no longer shows intake modal. Add "Prepare Session" option (dropdown or secondary button) |
| ProceduralNavigationPage | Remove IntakeFormModal gating. Add "Session Variables" panel button. Inline prompts on steps with unfilled variables |
| StepDetail | Render inline input prompts for unresolved [VAR:x] references |
| Quick Start page | New "Prepared for You" section showing assigned prepared sessions |
| Session History | New "Prepared" tab/filter showing prepared sessions |
| Prepare Session form | New modal/page: select flow, fill variables, assign engineer, save |
| Session completion | Soft warning if required variables still empty |
What Gets Removed
IntakeFormModal.tsx— no longer used as a blocking gate (may repurpose as the "Prepare Session" form)- Required-field validation in
POST /sessionsfor intake form fields - The
showIntakeForm/ intake modal state inProceduralNavigationPage
Implementation Phases
Phase 1: Mutable Variables + Inline Prompts
Files: sessions.py, variableResolver.ts, StepDetail.tsx, ProceduralNavigationPage.tsx
- Add
PATCH /sessions/{id}/variablesendpoint - Remove intake form required-field blocking from
POST /sessions - Update
resolveVariables()to identify unresolved variables - Build inline variable prompt component for
StepDetail - Make "View Parameters" panel editable
- Remove
IntakeFormModalgating fromProceduralNavigationPage
Phase 2: Prepared Sessions
Files: sessions.py, session.py (schemas), migration, PrepareSessionModal.tsx, QuickStartPage.tsx, SessionHistoryPage.tsx
- Migration: add
prepared_by_id,assigned_to_idto sessions table POST /sessions/prepareendpointGET /sessionsfilter support forassigned_to_idand prepared status- Prepare Session modal/form (reuse IntakeFormModal field rendering)
- "Prepared for You" section on Quick Start
- "Prepared" filter on Session History
Phase 3: Polish
- Soft completion warning for unfilled required variables
- Prepared session staleness indicator (optional)
- Notification when a session is prepared/assigned to you (optional, future)
Verification
- Start a procedural flow without filling any variables → flow starts immediately, no modal
- Navigate to a step with
[VAR:server_name]→ see inline input prompt - Fill the variable inline → value resolves across all steps
- Open Session Variables panel → see all fields, edit one → reflected in steps
- Prepare a session from flow detail page → assign to another engineer
- Log in as assigned engineer → see prepared session in Quick Start queue
- Click prepared session → flow opens with variables pre-filled, execute normally
- Complete a session with one unfilled required variable → see soft warning
- Export session → variables resolved in output, unfilled ones show as
[VAR:x]or blank