# 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`

```sql
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
