feat: Add custom step creation and backend support (Phase 3A: B.8-B.10, B.13)

Implements custom step creation forms and backend persistence:

Task B.8 - StepForm Component:
- Comprehensive form for creating custom steps
- Step type selection (decision/action/solution) with descriptions
- Required fields: title, instructions (markdown supported)
- Optional fields: help text, commands (dynamic array), category, tags
- Visibility control (private/team/public)
- Save to library checkbox
- Full validation with error display
- Dynamic command management (add/remove, label + command)
- Tag input with Enter key support

Task B.9 - CustomStepModal:
- Tabbed modal interface
- Tab 1: "Type My Own" - embeds StepForm
- Tab 2: "Browse Library" - embeds StepLibraryBrowser
- Handles both saved steps (API) and drafts (no save)
- Loading states during step creation
- Error handling with user feedback
- Returns Step or CustomStepDraft to parent

Task B.10 - Backend Custom Steps Support:
- Database migration: add custom_steps JSONB column to sessions
- Updated Session model with custom_steps field
- Updated SessionResponse schema with custom_steps
- Updated SessionUpdate schema to accept custom_steps
- Migration ready to run: 4cdb5cba1aff

Task B.13 - Session Types Updates:
- Added CustomStep and CustomStepDraft interfaces
- Updated Session interface with custom_steps field
- Updated SessionUpdate interface
- Exported step types from types/index.ts
- Full TypeScript support for custom step integration

Remaining tasks: B.11 (TreeNavigationPage integration), B.12 (Export)
Build tested successfully.

Related: Issues #8, #9, #10

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-02-03 19:15:36 -05:00
parent fc7fa1a17c
commit 009c60fbc3
7 changed files with 602 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ export * from './invite'
export * from './tag'
export * from './category'
export * from './folder'
export * from './step'
// API response wrapper types
export interface PaginatedResponse<T> {

View File

@@ -1,4 +1,5 @@
import type { TreeStructure } from './tree'
import type { Step, StepContent } from './step'
export interface DecisionRecord {
node_id: string
@@ -11,6 +12,21 @@ export interface DecisionRecord {
attachments: string[]
}
export interface CustomStep {
id: string
inserted_after_node_id: string
step_data: Step | CustomStepDraft
timestamp: string
}
export interface CustomStepDraft {
title: string
step_type: 'decision' | 'action' | 'solution'
content: StepContent
category_id?: string
tags?: string[]
}
export interface Session {
id: string
tree_id: string
@@ -18,6 +34,7 @@ export interface Session {
tree_snapshot: TreeStructure
path_taken: string[]
decisions: DecisionRecord[]
custom_steps: CustomStep[]
started_at: string
completed_at: string | null
ticket_number: string | null
@@ -34,6 +51,7 @@ export interface SessionCreate {
export interface SessionUpdate {
path_taken?: string[]
decisions?: DecisionRecord[]
custom_steps?: CustomStep[]
ticket_number?: string
client_name?: string
}