Adds a new "procedural" tree type for linear step-by-step project workflows (domain controller setup, M365 onboarding, VPN config, etc). Includes intake form builder, two-panel step navigation, variable resolution, procedural exports, 3 seed templates, and UI rename from "Trees" to "Flows". Also archives 19 implemented plan docs and creates deferred features backlog. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
28 KiB
Procedural Flows — Unified Implementation Plan
Plan Comparison & Analysis
Before diving into the merged plan, here's how the three source plans compared and why specific choices were made.
Plan 1 (Design Document — Claude + Michael)
Strengths: Richest feature vision. Best product thinking — pre-flight forms with field grouping, rich step types (action/informational/verification/warning), PowerShell snippets with variable injection, section headers within procedures, verification checks with multiple types (checkbox/text/screenshot), time estimates per step, and a strong example template library (DC Build, M365 Onboarding). Excellent as a product requirements document.
Weaknesses: Created entirely new database tables (ProcedureTemplate, FormField, ProcedureStep, ProcedureInstance) rather than extending the existing Tree model. This would duplicate a huge amount of existing infrastructure — authentication, CRUD endpoints, export pipelines, session management — all of which already work. No awareness of the existing codebase's file structure, variable resolution system ([VAR:name]), Zustand stores, or migration numbering. Not directly actionable by Claude Code without significant translation.
Verdict: Best product vision, weakest implementation strategy.
Plan 2 (Procedural Flow Framework v1)
Strengths: Strong architectural awareness — adds flow_mode to the existing Tree model rather than creating parallel tables. Introduces dedicated procedural node types (procedure_step, procedure_end) which gives clean separation. Thorough validation rules (acyclic graph, single end node, no branching). Good test case coverage. Handles markdown parser/serializer compatibility (code-mode). Warning-only policy for missing required fields is pragmatic.
Weaknesses: Introduces new node types which adds complexity to the existing node system — every component that switches on node type needs updating. Six implementation phases is a lot of surface area. The intake form is "warning-only" for required fields, which could let techs start procedures with missing critical data (like no IP address for a DC build). Doesn't specify the runtime UX in much detail — no two-panel layout, no progress tracking specifics. Doesn't reference specific existing files or infrastructure to reuse.
Verdict: Strongest validation and publish constraints, but over-engineered node type approach.
Plan 3 (Implementation Plan)
Strengths: Most implementation-ready by far. References exact file paths, existing infrastructure (variable_service.py, variableResolver.ts, session_variables JSONB field from migration 028, treeEditorStore patterns), and specific migration numbering (035). Uses tree_type on the existing Tree model — minimal schema changes. Creates a separate proceduralEditorStore.ts (clean separation) while reusing existing patterns. The two-panel navigation UX (step checklist + step detail) is concrete and buildable. Flat step array is simpler than a node graph for linear procedures. Four focused phases instead of six. The file manifest table makes it crystal clear what gets created vs modified.
Weaknesses: Lighter on product features — no step types (action/warning/verification), no PowerShell snippet support, no time estimates, no section headers, no verification checks. Uses [VAR:name] syntax (existing) rather than {{variable}} (more intuitive but would require a new resolver). Doesn't include template seeding in its phases. Less detail on the intake form field types compared to Plans 1 and 2.
Verdict: Highest chance of successful implementation, needs feature enrichment from Plans 1 and 2.
Summary Matrix
| Criteria | Plan 1 (Design Doc) | Plan 2 (Framework v1) | Plan 3 (Impl Plan) |
|---|---|---|---|
| Codebase awareness | ❌ None | ⚠️ Partial | ✅ Exact file paths |
| Reuses existing infra | ❌ New tables | ✅ Extends Tree model | ✅ Extends Tree + reuses variable system |
| Feature richness | ✅ Richest | ⚠️ Medium | ⚠️ Lean |
| UX detail | ✅ Runner + Builder + Dashboard | ⚠️ Runtime mentioned | ✅ Two-panel layout specified |
| Implementation clarity | ❌ Conceptual | ⚠️ Phased but abstract | ✅ File-level specificity |
| Validation rules | ⚠️ Basic | ✅ Thorough | ⚠️ Basic |
| Chance of success | ⚠️ Low (too much new) | ⚠️ Medium (complex) | ✅ High (incremental) |
| Claude Code ready | ❌ No | ⚠️ Partially | ✅ Yes |
Merge Strategy
Use Plan 3 as the structural backbone (file paths, migration approach, store patterns, reuse strategy), enrich with Plan 1's product features (rich step types, PowerShell snippets, verification checks, time estimates, section headers, template examples), and incorporate Plan 2's validation rules (publish constraints, acyclic enforcement, explicit end node requirement).
Unified Implementation Plan
Architecture Decision
Add a tree_type enum field ('troubleshooting' | 'procedural') to the existing Tree model. Same table, same API endpoints, different behavior based on type. Procedural flows store steps as a flat ordered array (not a node graph) and include an intake form schema for pre-flight data collection. This avoids duplicating the entire tree infrastructure while giving procedural flows their own editor, navigation, and validation.
Variable Syntax
Use the existing [VAR:name] infrastructure from variable_service.py and variableResolver.ts. This is already battle-tested in the codebase. No need to introduce {{variable}} syntax and a parallel resolver.
Scope
In scope:
tree_type+intake_formfields on Tree model (migration 035)- Procedural tree validation (linear steps only, no decision nodes, explicit end)
- Rich step model (types, warnings, time estimates, verification, PowerShell, section headers)
- Intake form builder in the editor with field validation
- Intake form modal before session start
- Two-panel procedural navigation (step checklist + step detail)
- Variable resolution in step content via existing
[VAR:name]infrastructure - Procedural-aware exports
- Dashboard tabs (Troubleshooting | Procedures)
- Two seeded templates (DC Build, M365 User Onboarding)
Out of scope (deferred):
- Conditional steps (steps that show/hide based on form values)
- Procedural code-mode editor
- Step templates / reusable step library
- Approval workflows
- Screenshot verification type
- Session assignment/handoff
- AI-assisted template generation
- Automated PowerShell execution
Data Model
Migration 035: 035_add_tree_type_and_intake_form.py
tree_type: String(20), NOT NULL, server_default='troubleshooting'
- Check constraint: IN ('troubleshooting', 'procedural')
- Indexed for filtering
intake_form: JSONB, nullable, default NULL
- Stores the intake form field definitions (see IntakeFormField schema below)
Existing trees automatically get tree_type='troubleshooting' and intake_form=NULL. No data migration needed.
Intake Form Field Schema
Each field in the intake_form JSONB array supports:
| Property | Type | Required | Description |
|---|---|---|---|
variable_name |
string | Yes | Variable key used in [VAR:name] tokens. Pattern: ^[a-z][a-z0-9_]*$ |
label |
string | Yes | Display label (e.g., "Server Name") |
field_type |
enum | Yes | text, textarea, number, ip_address, email, select, multi_select, checkbox, password |
required |
boolean | Yes | Whether the field must be filled before starting |
options |
string[] | Conditional | Required for select and multi_select types |
placeholder |
string | No | Hint text shown in empty field |
help_text |
string | No | Tooltip or description explaining the field |
default_value |
string | No | Pre-filled default |
group_name |
string | No | Section grouping header (e.g., "Network Settings") |
display_order |
integer | Yes | Position in form (1, 2, 3...) |
validation |
object | No | Validation config (see below) |
Field Validation Config
{
"min_length": 1,
"max_length": 15,
"pattern": "^[A-Za-z0-9-]+$",
"pattern_message": "Only letters, numbers, and hyphens allowed",
"format": "ipv4",
"min_value": 1,
"max_value": 4094,
"min_selections": 1,
"max_selections": 5
}
Format validators by field type:
ip_address→ validates IPv4 format (e.g.,192.168.1.10)email→ validates email formatnumber→ validates numeric rangetext→ validates length and optional regex patternpassword→ validates minimum lengthselect→ value must match one of the defined optionsmulti_select→ values must match defined options, respects min/max selections
Procedural Step Schema
Procedural trees store steps as a flat ordered array in the tree's node structure. Each step has:
| Property | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique step identifier |
type |
enum | Yes | procedure_step or procedure_end |
step_number |
integer | Yes | Order position (1, 2, 3...) |
title |
string | Yes | Step title (e.g., "Configure Static IP Address") |
description |
string | Yes | Instruction text with [VAR:name] placeholders |
content_type |
enum | Yes | action, informational, verification, warning |
estimated_minutes |
integer | No | Time estimate for this step |
warning_text |
string | No | Caution/warning banner text |
verification_prompt |
string | No | What to verify before marking complete |
verification_type |
enum | No | checkbox (confirm done) or text_input (enter observed value) |
commands |
string | No | PowerShell/CLI command block with [VAR:name] support and copy-to-clipboard |
expected_outcome |
string | No | What should happen after executing the step |
notes_enabled |
boolean | Yes | Whether tech can add freeform notes (default: true) |
section_header |
string | No | Section divider text (e.g., "Phase 2: AD Configuration") |
reference_url |
string | No | Link to external documentation |
next_node_id |
string | Conditional | Required for procedure_step, points to next step. Not present on procedure_end. |
Procedural Publish Validation Rules
When publishing a procedural tree, enforce:
- Tree must contain at least one
procedure_stepand exactly oneprocedure_end - Only
procedure_stepandprocedure_endnode types are allowed (no decision nodes) - No branching — each
procedure_steppoints to exactly onenext_node_id - Graph must be acyclic (no loops)
- All steps must be reachable from the root node
- The chain must terminate at the single
procedure_endnode - No orphan nodes
- If
intake_formis defined, allvariable_namevalues must be unique selectandmulti_selectfields must have at least one option defined
Session Variables
SessionCreate accepts optional session_variables: dict[str, str] to store intake form values. These are persisted in the existing session_variables JSONB field (already exists from migration 028).
At session start for procedural trees:
- If
intake_formexists → validate required fields are present - Required fields that are missing → block start (not warning-only; these are critical operational data)
- Optional fields that are missing → allowed, unresolved
[VAR:name]tokens render as highlighted placeholders:[server_name — not provided]
Phase 1: Backend Foundation
Files to Modify
| File | Changes |
|---|---|
backend/alembic/versions/035_add_tree_type_and_intake_form.py |
CREATE — Migration adding tree_type and intake_form columns |
backend/app/models/tree.py |
Add tree_type and intake_form mapped columns |
backend/app/schemas/tree.py |
Add IntakeFormField schema, field type enum, validation schema. Add tree_type + intake_form to TreeCreate, TreeUpdate, TreeResponse, TreeListResponse. Add session_variables to SessionCreate. |
backend/app/core/tree_validation.py |
Add validate_procedural_structure() — enforces all publish rules (linear chain, single end, no branching, no cycles, no orphans). Update can_publish_tree() to dispatch by tree_type. |
backend/app/api/endpoints/sessions.py |
start_session: accept session_variables, validate required intake fields for procedural trees, store in session. Include tree_type in tree_snapshot. |
backend/app/api/endpoints/trees.py |
Add optional tree_type query filter to tree listing. Ensure fork copies tree_type + intake_form. |
Tests
- Existing trees default to
tree_type='troubleshooting'andintake_form=NULL - Create/update/list/filter by
tree_type - Procedural publish rejected when: branching exists, cycles exist, missing end node, multiple end nodes, orphan nodes
- Procedural publish accepted for valid linear chain
- Session start with
session_variablespopulated from intake - Required intake fields missing → session start blocked
- Optional fields missing → session starts, variables unresolved
- Fork preserves
tree_typeandintake_form - All existing troubleshooting tests still pass
Deliverable
A procedural tree can be created, validated, published, and started via API with intake form variables stored in the session.
Phase 2: Procedural Editor (Frontend)
Files to Create
| File | Purpose |
|---|---|
frontend/src/store/proceduralEditorStore.ts |
New Zustand store (immer + zundo for undo/redo). Flat step array operations: add, remove, update, reorder. Intake form field operations: add, remove, update, reorder. getTreeForSave() builds the API payload. Follows patterns from treeEditorStore.ts. |
frontend/src/pages/ProceduralEditorPage.tsx |
Route: /flows/new?type=procedural and /flows/:id/edit (when tree_type=procedural). Three sections: metadata (name, description, category, tags), intake form builder, step list editor. |
frontend/src/components/procedural-editor/IntakeFormBuilder.tsx |
Add/remove/reorder form field definitions. Drag-to-reorder via existing DnD library. Live preview panel showing how the form will appear to techs. |
frontend/src/components/procedural-editor/IntakeFieldEditor.tsx |
Single field configuration: label, variable_name, field_type, required toggle, options list (for select/multi_select), placeholder, help_text, default_value, group_name, validation rules. |
frontend/src/components/procedural-editor/StepList.tsx |
Ordered step list with drag handles. Inline title editing. Section header support — steps grouped under optional section dividers. Step type badges (action/verification/warning/informational). |
frontend/src/components/procedural-editor/StepEditor.tsx |
Expanded step editing: title, content_type selector, description with markdown support, warning_text, estimated_minutes, verification_prompt + verification_type, commands (PowerShell block), expected_outcome, reference_url, notes_enabled toggle, section_header. Highlights [VAR:name] tokens and shows available variables from intake form. |
Files to Modify
| File | Changes |
|---|---|
frontend/src/types/tree.ts |
Add TreeType = 'troubleshooting' | 'procedural'. Add IntakeFormField, IntakeFieldValidation, ProceduralStep, StepContentType interfaces. Add tree_type + intake_form to Tree, TreeListItem, TreeCreate. |
frontend/src/pages/MyTreesPage.tsx |
"New" button offers type choice (troubleshooting vs procedural). Route to appropriate editor. |
frontend/src/pages/TreeLibraryPage.tsx |
Add tab filter by tree_type. Different icon for procedural flows (ListOrdered or similar). |
frontend/src/router.tsx |
Add routes for ProceduralEditorPage and ProceduralNavigationPage. |
Deliverable
Admins/editors can create and edit procedural flow templates with intake forms and rich steps through a dedicated editor UI. Dashboard shows procedures in a filtered view.
Phase 3: Procedural Navigation & Runtime (Frontend)
Files to Create
| File | Purpose |
|---|---|
frontend/src/pages/ProceduralNavigationPage.tsx |
Route: /flows/:id/navigate. Two-panel layout: step checklist (left sidebar, ~280px) + step detail (right). Progress bar: "Step X of Y" with percentage. "Mark Complete & Next" button. Running time tracker (elapsed vs estimated). Collapsible sidebar showing intake form data for reference. |
frontend/src/components/procedural/IntakeFormModal.tsx |
Modal rendered before session start. Renders form from intake_form definitions with proper input types, validation, and grouping by group_name. Required fields enforced. Validates on submit. |
frontend/src/components/procedural/StepChecklist.tsx |
Left panel: numbered list, completed checkmarks, current step highlighted, section header dividers. Click to jump to any step. |
frontend/src/components/procedural/StepDetail.tsx |
Right panel: step title + number, content_type indicator badge, resolved description (variables injected), warning banner (if warning_text exists), commands block with copy-to-clipboard, expected outcome, verification prompt + input, notes field, reference link, estimated time badge. |
frontend/src/components/procedural/ProgressBar.tsx |
Step count + percentage bar + elapsed time vs total estimated time. |
frontend/src/components/procedural/CompletionSummary.tsx |
Shown when all steps complete. Displays: all form data, step completion timestamps, tech notes per step, verification values, total time elapsed. This is the audit trail view. |
Session Lifecycle
- User clicks "Start" on a procedural flow
- If
intake_formexists → showIntakeFormModal, collect and validate values - Call
POST /sessionswithsession_variablesfrom the form - Navigate to step 1, render two-panel layout
- Each step: tech reads instructions (with variables resolved), performs work, optionally adds notes, fills verification if required, clicks "Mark Complete & Next"
- Step completion creates a
DecisionRecord(reuses existing session update API) - Completing last step →
CompletionSummaryview → session marked complete
Variable Resolution Behavior
- Resolved variables render as highlighted/bold inline text (visually distinct from surrounding content)
- Unresolved optional variables render as
[server_name — not provided]with a muted/highlighted style - Variables in commands blocks also resolve, so PowerShell is copy-paste ready
- Intake form data panel remains visible in a collapsible sidebar for quick reference
Deliverable
Technicians can fill out a pre-flight form, step through a procedure with injected variables, track completion, add notes, and see a completion summary.
Phase 4: Export, Polish & Template Seeding
Export Changes
| File | Changes |
|---|---|
backend/app/services/export_service.py |
Detect tree_type from tree_snapshot. Procedural format: numbered checklist with completion status, step times, tech notes. Include "Project Parameters" section from session_variables. All 4 formats (markdown, text, html, psa). |
Session Detail Changes
| File | Changes |
|---|---|
frontend/src/pages/SessionDetailPage.tsx |
Detect procedural sessions from tree_snapshot.tree_type. Show step checklist layout with completion data instead of decision timeline. |
Dashboard Tab Integration
| File | Changes |
|---|---|
frontend/src/pages/MyTreesPage.tsx |
Add tab bar: Troubleshooting |
| Navigation sidebar | Add dedicated "Procedures" menu item linking to the Procedures tab. |
Template Seeding
Create two seed templates that demonstrate all features:
Template 1: New Domain Controller Build
Intake Form Fields:
| Variable | Label | Type | Required | Validation |
|---|---|---|---|---|
server_name |
Server Name | text | Yes | Max 15 chars, no spaces |
static_ip |
Static IP Address | ip_address | Yes | IPv4 format |
subnet_mask |
Subnet Mask | ip_address | Yes | IPv4 format |
default_gateway |
Default Gateway | ip_address | Yes | IPv4 format |
preferred_dns |
Preferred DNS Server | ip_address | Yes | IPv4 format |
alternate_dns |
Alternate DNS Server | ip_address | No | IPv4 format |
domain_name |
Domain Name (FQDN) | text | Yes | Must contain a dot |
netbios_name |
NetBIOS Domain Name | text | Yes | Max 15 chars |
dsrm_password |
DSRM Password | password | Yes | Min 12 chars |
server_roles |
Roles to Install | multi_select | Yes | Options: AD DS, DNS, DHCP, File Services |
site_name |
AD Site Name | text | No | Default: Default-First-Site-Name |
ticket_number |
Ticket / Change # | text | No | For documentation |
Steps (abbreviated — full steps would include descriptions, commands, warnings, and verifications):
| # | Section | Title | Type | Est. Time | Has Verification |
|---|---|---|---|---|---|
| 1 | OS Configuration | Rename Server to [VAR:server_name] | action | 5 min | Yes — confirm hostname |
| 2 | OS Configuration | Configure Static IP [VAR:static_ip] | action | 5 min | Yes — confirm IP set |
| 3 | OS Configuration | Install Server Roles: [VAR:server_roles] | action | 15 min | Yes — confirm roles |
| 4 | AD Installation | Promote to Domain Controller | action | 20 min | Yes — confirm reboot |
| 5 | AD Installation | Verify AD DS Service Running | verification | 5 min | Yes — service status |
| 6 | DNS Configuration | Configure DNS Forwarders | action | 5 min | No |
| 7 | DNS Configuration | Create Reverse Lookup Zone | action | 5 min | No |
| 8 | Verification | Run dcdiag /v | verification | 10 min | Yes — enter pass/fail |
| 9 | Verification | Run repadmin /replsummary | verification | 5 min | Yes — enter pass/fail |
| 10 | Cleanup | Document Completion | informational | 5 min | No |
| — | — | Procedure Complete | procedure_end | — | — |
Template 2: Microsoft 365 New User Onboarding
Intake Form Fields:
| Variable | Label | Type | Required |
|---|---|---|---|
first_name |
First Name | text | Yes |
last_name |
Last Name | text | Yes |
display_name |
Display Name | text | Yes |
email_address |
Email Address | Yes | |
job_title |
Job Title | text | No |
department |
Department | text | No |
manager_email |
Manager Email | No | |
license_type |
License Type | select | Yes |
security_groups |
Security Groups | multi_select | No |
distribution_lists |
Distribution Lists | multi_select | No |
shared_mailboxes |
Shared Mailboxes | multi_select | No |
temp_password |
Temporary Password | password | Yes |
Steps: Create user account → Assign [VAR:license_type] license → Add to security groups [VAR:security_groups] → Add to distribution lists → Configure shared mailbox access → Set manager → Verify user can sign in → Document completion → Procedure Complete (end)
Deliverable
Procedures export cleanly with all data. Dashboard has tabs. Two real-world templates are available out of the box.
Key Files Manifest
| Action | File |
|---|---|
| CREATE | backend/alembic/versions/035_add_tree_type_and_intake_form.py |
| CREATE | frontend/src/store/proceduralEditorStore.ts |
| CREATE | frontend/src/pages/ProceduralEditorPage.tsx |
| CREATE | frontend/src/pages/ProceduralNavigationPage.tsx |
| CREATE | frontend/src/components/procedural-editor/IntakeFormBuilder.tsx |
| CREATE | frontend/src/components/procedural-editor/IntakeFieldEditor.tsx |
| CREATE | frontend/src/components/procedural-editor/StepList.tsx |
| CREATE | frontend/src/components/procedural-editor/StepEditor.tsx |
| CREATE | frontend/src/components/procedural/IntakeFormModal.tsx |
| CREATE | frontend/src/components/procedural/StepChecklist.tsx |
| CREATE | frontend/src/components/procedural/StepDetail.tsx |
| CREATE | frontend/src/components/procedural/ProgressBar.tsx |
| CREATE | frontend/src/components/procedural/CompletionSummary.tsx |
| MODIFY | backend/app/models/tree.py — add tree_type, intake_form columns |
| MODIFY | backend/app/schemas/tree.py — add schemas, update CRUD schemas |
| MODIFY | backend/app/core/tree_validation.py — add procedural validation |
| MODIFY | backend/app/api/endpoints/sessions.py — accept session_variables |
| MODIFY | backend/app/api/endpoints/trees.py — add tree_type filter, fork support |
| MODIFY | backend/app/services/export_service.py — procedural export format |
| MODIFY | frontend/src/types/tree.ts — add procedural types |
| MODIFY | frontend/src/router.tsx — add procedural routes |
| MODIFY | frontend/src/pages/MyTreesPage.tsx — tabs + type selector |
| MODIFY | frontend/src/pages/TreeLibraryPage.tsx — type filter |
| MODIFY | frontend/src/pages/SessionDetailPage.tsx — procedural session view |
Reusable Existing Infrastructure
These already exist and should be reused directly:
- Variable resolution:
backend/app/services/variable_service.py+frontend/src/lib/variableResolver.ts— already handles[VAR:name]tokens - Session model:
session_variablesJSONB field already exists (migration 028) - Drag and drop: existing DnD library used in tree editor
- Export pipeline: redaction + variable resolution already in place, just needs procedural formatting branch
- Zustand patterns:
treeEditorStore.tsas reference forproceduralEditorStore(immer + zundo) - Authentication & RBAC: existing auth middleware, no changes needed
- Organization scoping: existing org/client filtering applies automatically
Compatibility Notes
- Existing troubleshooting trees remain default (
tree_type='troubleshooting') and are completely unchanged - Existing sessions, exports, and navigation behavior remain intact
- No migration of existing tree data required beyond adding the new columns with defaults
- All existing tests must continue to pass
Verification Checklist
Backend
pytest --override-ini="addopts="— all existing + new tests pass- Migration 035 applies cleanly and rolls back cleanly
- Existing trees get
tree_type='troubleshooting'automatically
Frontend
npm run build— clean tsc + vite build- All existing troubleshooting flows work identically
Manual QA
- Create procedural flow with intake form in editor
- Publish procedural flow (validation passes for valid, rejects invalid)
- Start procedure → fill intake form → navigate all steps → complete
- Verify variables resolve correctly in step text and commands
- Verify unresolved optional variables show placeholder text
- Verify step completion tracking (checkboxes, timestamps, notes)
- Verify completion summary shows all data
- Export completed procedure in all 4 formats
- Both seeded templates run end-to-end correctly
- Dashboard tabs filter correctly
- No regressions in troubleshooting flow functionality
Future Considerations (Deferred)
These are documented for future planning but are explicitly out of scope:
- Conditional steps: Steps that show/hide based on intake form values
- Branching hybrid: Mini decision-tree within a procedure step
- AI-assisted template generation: Use Claude API to generate templates from descriptions
- Approval workflows: Manager sign-off before procedure can start
- Sub-checklists within steps: A step containing its own checklist
- Template marketplace: Share templates between organizations
- Automated execution: Execute PowerShell commands remotely and capture output
- Screenshot verification: Attach image proof to verification checks
- Code-mode editor: Markdown-based authoring for procedural flows