Files
resolutionflow/docs/plans/archive/2026-03-23-unified-sessions.md
Michael Chihlas cbb4b25671
All checks were successful
Mirror to GitHub / mirror (push) Successful in 5s
CI / frontend (pull_request) Successful in 6m42s
CI / e2e (pull_request) Successful in 10m11s
CI / backend (pull_request) Successful in 10m43s
fix(ui): drop setState-in-effect in useAuthSessionExpiry
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>
2026-05-13 20:15:11 -04:00

5.7 KiB

Unified Sessions — Migration Plan

Date: 2026-03-23 Status: Implementation ready Goal: Merge assistant chat into the ai_sessions system so both guided (FlowPilot) and free-form (chat) sessions share the same data model, history, and action system.

Problem

Three separate conversation systems exist:

  1. assistant_chats — free-form chat, JSONB messages inline, no steps
  2. ai_sessions + ai_session_steps — guided FlowPilot, separate steps table
  3. ai_chat_sessions — flow builder (unrelated, leave alone)

This causes:

  • No unified session history
  • Assistant chats missing Resolve/Escalate/Update actions
  • Dashboard can't show assistant chats in active/recent
  • Two separate API surfaces to maintain

Solution

Add session_type to ai_sessions. Chat sessions use conversation_messages JSONB for message history (already exists). Both types share the same status, PSA, escalation, and documentation features.

Data Model Changes

Migration: Add session_type to ai_sessions

ALTER TABLE ai_sessions ADD COLUMN session_type VARCHAR(10) NOT NULL DEFAULT 'guided';
-- Values: 'guided' (FlowPilot), 'chat' (assistant)

How chat sessions use ai_sessions

ai_sessions column Chat usage
session_type 'chat'
intake_type 'free_text'
intake_content {text: "first message"}
conversation_messages Full chat history as JSONB array [{role, content}]
status Same: active/resolved/escalated/paused/abandoned
problem_summary AI-generated from first few messages
problem_domain AI-detected domain
step_count Message count (for display)
resolution_summary Set on resolve
escalation_reason Set on escalate
All PSA fields Same — can link tickets, push notes
All timestamps Same

What chat sessions DON'T use

  • ai_session_steps table — no steps, messages are in conversation_messages
  • matched_flow_id / match_score — no flow matching
  • confidence_tier / confidence_score — no structured confidence
  • system_prompt_snapshot — could store chat system prompt

New field on ai_sessions

  • title (String 255, nullable) — chat sessions need a title for the sidebar. Guided sessions can use problem_summary.

Implementation Phases

Phase 1: Backend — Model & Migration

  • Alembic migration: add session_type VARCHAR(10) default 'guided', add title VARCHAR(255) nullable
  • Update AISession model with new columns
  • Update schemas: add session_type and title to response schemas
  • Add session_type filter to GET /ai-sessions endpoint

Phase 2: Backend — Chat API on ai_sessions

  • Create new endpoints or extend existing:
    • POST /ai-sessions with session_type: 'chat' — creates a chat session
    • POST /ai-sessions/{id}/chat — send message, get AI response (appends to conversation_messages)
    • Reuse existing: resolve, escalate, pause, abandon, status-update
  • Chat AI service: takes conversation_messages, calls Anthropic, appends response
  • Auto-generate title from first message (like current assistant chat does)
  • Auto-detect problem_domain from conversation

Phase 3: Frontend — Unified Session History

  • Update SessionHistoryPage to show both types
  • Add type icon: compass/route for guided, message-circle for chat
  • Session detail page routes correctly based on type
  • Add session_type filter option

Phase 4: Frontend — Assistant Chat on ai_sessions

  • Update AssistantChatPage to use ai_sessions API instead of assistant_chats
  • Chat sidebar queries ai_sessions with session_type=chat
  • Messages read from / write to conversation_messages
  • Add header actions: Resolve / Escalate / Share Update / Pause / Close
  • Status update modal works the same as FlowPilot

Phase 5: Frontend — Dashboard Integration

  • ActiveFlowPilotSessions includes chat sessions (both types)
  • RecentFlowPilotSessions includes resolved chats
  • Type icon on each card so users see the difference at a glance

Phase 6: Cleanup

  • Migrate existing assistant_chat data to ai_sessions (optional — could just start fresh for pilot)
  • Deprecate /assistant/* API endpoints
  • Remove assistant_chats model (post-pilot)

Visual Differentiators

Type Icon Badge color Label
Guided (FlowPilot) <Route size={14} /> cyan "Guided"
Chat (Assistant) <MessageCircle size={14} /> purple/violet "Chat"

API Surface (after migration)

All under /ai-sessions:

Endpoint Both types? Notes
POST /ai-sessions Yes session_type field determines behavior
GET /ai-sessions Yes Filter by session_type optional
GET /ai-sessions/{id} Yes Returns full session with messages or steps
POST /ai-sessions/{id}/chat Chat only Send/receive messages
POST /ai-sessions/{id}/respond Guided only Step response
POST /ai-sessions/{id}/resolve Both Same resolve flow
POST /ai-sessions/{id}/escalate Both Same escalation
POST /ai-sessions/{id}/pause Both Same pause
POST /ai-sessions/{id}/abandon Both Same abandon
POST /ai-sessions/{id}/status-update Both Same status updates

Risk Assessment

  • Low risk: Adding columns to ai_sessions is additive, no existing data changes
  • Medium risk: Frontend routing — need to route to correct page based on session_type
  • Data migration: Can skip for pilot — start with fresh chat sessions on new system. Old assistant_chats remain accessible via old API until removed.
  • Rollback: session_type column is additive, old assistant_chat endpoints can stay as fallback