## Overview
Complete vertical slice delivering operator chat functionality end-to-end. After this task, operators can send/receive messages in remote support sessions with full UI.
## Verification (How to test after deployment)
1. Create a new remote support session
2. Open the session as operator
3. See chat panel (collapsible) alongside video
4. Send a message → appears in chat
5. Refresh page → message persists
6. End session → chat history still visible
## Implementation Scope
### 1. Database & Model
```ruby
# Migration: create_support_session_messages
create_table :support_session_messages do |t|
t.references :support_session, null: false, foreign_key: true, index: true
t.references :user, null: true, foreign_key: true
t.string :participant_type, null: false # 'operator' or 'guest'
t.string :participant_name, null: false
t.text :content, null: false
t.jsonb :metadata, default: {}
t.timestamps
end
add_index :support_session_messages, [:support_session_id, :created_at]
```
Model: `SupportSessionMessage`
- belongs_to :support_session
- belongs_to :user, optional: true
- enum participant_type: { operator: 'operator', guest: 'guest' }
- validates :content, presence: true, length: { maximum: 5000 }
- scope :chronological, -> { order(created_at: :asc) }
- def to_broadcast_payload
### 2. Service Object
`RemoteSupport::SendChatMessageService`
- Validates session not ended
- Creates message record
- Broadcasts via ActionCable (simpler than NATS for now)
- Returns Success(message) or Failure
### 3. API Endpoints (Operator only)
```ruby
# routes.rb
resources :remote_support_sessions, path: 'remote_support/sessions' do
resources :messages, only: [:index, :create], controller: 'remote_support/session_messages'
end
```
- `GET /remote_support/sessions/:id/messages` - fetch history
- `POST /remote_support/sessions/:id/messages` - send message
### 4. ActionCable Channel
`SupportSessionChatChannel` - broadcasts to `support_session_chat:{id}`
- Operator subscribes by session_id (authenticated)
- Messages broadcast on create
### 5. React Component
`SessionChatPanel.jsx` - collapsible chat panel
- Message list with DaisyUI chat bubbles
- Input with send button
- Auto-scroll
- Connection status badge
### 6. Integration
Modify `OperatorCommandCenter.jsx`:
- Add chat panel to layout
- Chat toggle button in control bar
- Fetch initial messages via props
- Subscribe to ActionCable for real-time
Modify `session_detail_component.rb`:
- Fetch messages for props
- Pass to turbo_mount
## Files to Create
- `db/migrate/xxx_create_support_session_messages.rb`
- `app/models/support_session_message.rb`
- `app/services/remote_support/send_chat_message_service.rb`
- `app/controllers/remote_support/session_messages_controller.rb`
- `app/channels/support_session_chat_channel.rb`
- `app/javascript/components/remote_support/SessionChatPanel.jsx`
- `spec/models/support_session_message_spec.rb`
- `spec/services/remote_support/send_chat_message_service_spec.rb`
- `spec/requests/remote_support/session_messages_spec.rb`
- `spec/factories/support_session_messages.rb`
## Files to Modify
- `app/models/support_session.rb` (add has_many)
- `config/routes.rb`
- `app/javascript/components/remote_support/OperatorCommandCenter.jsx`
- `app/components/remote_support/session_detail_component.rb`
- `app/components/remote_support/session_detail_component.html.haml`
## Overview
Complete vertical slice delivering operator chat functionality end-to-end. After this task, operators can send/receive messages in remote support sessions with full UI.
## Verification (How to test after deployment)
1. Create a new remote support session
2. Open the session as operator
3. See chat panel (collapsible) alongside video
4. Send a message → appears in chat
5. Refresh page → message persists
6. End session → chat history still visible
## Implementation Scope
### 1. Database & Model
```ruby
# Migration: create_support_session_messages
create_table :support_session_messages do |t|
t.references :support_session, null: false, foreign_key: true, index: true
t.references :user, null: true, foreign_key: true
t.string :participant_type, null: false # 'operator' or 'guest'
t.string :participant_name, null: false
t.text :content, null: false
t.jsonb :metadata, default: {}
t.timestamps
end
add_index :support_session_messages, [:support_session_id, :created_at]
```
Model: `SupportSessionMessage`
- belongs_to :support_session
- belongs_to :user, optional: true
- enum participant_type: { operator: 'operator', guest: 'guest' }
- validates :content, presence: true, length: { maximum: 5000 }
- scope :chronological, -> { order(created_at: :asc) }
- def to_broadcast_payload
### 2. Service Object
`RemoteSupport::SendChatMessageService`
- Validates session not ended
- Creates message record
- Broadcasts via ActionCable (simpler than NATS for now)
- Returns Success(message) or Failure
### 3. API Endpoints (Operator only)
```ruby
# routes.rb
resources :remote_support_sessions, path: 'remote_support/sessions' do
resources :messages, only: [:index, :create], controller: 'remote_support/session_messages'
end
```
- `GET /remote_support/sessions/:id/messages` - fetch history
- `POST /remote_support/sessions/:id/messages` - send message
### 4. ActionCable Channel
`SupportSessionChatChannel` - broadcasts to `support_session_chat:{id}`
- Operator subscribes by session_id (authenticated)
- Messages broadcast on create
### 5. React Component
`SessionChatPanel.jsx` - collapsible chat panel
- Message list with DaisyUI chat bubbles
- Input with send button
- Auto-scroll
- Connection status badge
### 6. Integration
Modify `OperatorCommandCenter.jsx`:
- Add chat panel to layout
- Chat toggle button in control bar
- Fetch initial messages via props
- Subscribe to ActionCable for real-time
Modify `session_detail_component.rb`:
- Fetch messages for props
- Pass to turbo_mount
## Files to Create
- `db/migrate/xxx_create_support_session_messages.rb`
- `app/models/support_session_message.rb`
- `app/services/remote_support/send_chat_message_service.rb`
- `app/controllers/remote_support/session_messages_controller.rb`
- `app/channels/support_session_chat_channel.rb`
- `app/javascript/components/remote_support/SessionChatPanel.jsx`
- `spec/models/support_session_message_spec.rb`
- `spec/services/remote_support/send_chat_message_service_spec.rb`
- `spec/requests/remote_support/session_messages_spec.rb`
- `spec/factories/support_session_messages.rb`
## Files to Modify
- `app/models/support_session.rb` (add has_many)
- `config/routes.rb`
- `app/javascript/components/remote_support/OperatorCommandCenter.jsx`
- `app/components/remote_support/session_detail_component.rb`
- `app/components/remote_support/session_detail_component.html.haml`