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>
This commit is contained in:
601
docs/plans/archive/2026-03-23-mid-session-status-updates.md
Normal file
601
docs/plans/archive/2026-03-23-mid-session-status-updates.md
Normal file
@@ -0,0 +1,601 @@
|
||||
# Mid-Session Status Updates — Feature Spec
|
||||
|
||||
> **Status:** IMPLEMENT NOW
|
||||
> **Date:** 2026-03-23
|
||||
> **Priority:** High — addresses real MSP workflow need during active troubleshooting
|
||||
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Engineers are mid-ticket, actively troubleshooting in FlowPilot, and need to share progress. Today they have to:
|
||||
|
||||
1. Context-switch out of FlowPilot
|
||||
2. Mentally summarize what they've done
|
||||
3. Write the update themselves (different tone for ticket notes vs. client emails)
|
||||
4. Paste it into their PSA or email
|
||||
|
||||
This breaks flow, wastes time, and produces inconsistent documentation. The AI already has full context — it should generate the update.
|
||||
|
||||
## Solution
|
||||
|
||||
**"Share Update"** — a button in the FlowPilot action bar that generates a context-aware status summary, tailored for either internal ticket notes or client-facing communication.
|
||||
|
||||
---
|
||||
|
||||
## User Flow
|
||||
|
||||
### 1. Trigger
|
||||
|
||||
Two ways to trigger:
|
||||
|
||||
- **Action bar button:** "Share Update" button (blue/cyan, positioned between Escalate and Pause)
|
||||
- **Chat command:** Engineer types "status update", "give me an update", "share progress" — FlowPilot recognizes the intent
|
||||
|
||||
### 2. Two-Step Selection
|
||||
|
||||
**Step 1 — Audience:**
|
||||
|
||||
FlowPilot responds:
|
||||
|
||||
> *"Who is this update for?"*
|
||||
>
|
||||
> **[Ticket Notes]** — Technical, for your PSA
|
||||
> **[Client Update]** — Professional, non-technical
|
||||
> **[Email Draft]** — Full email with subject line and sign-off
|
||||
|
||||
These are rendered as clickable option cards in the modal (or inline buttons in chat).
|
||||
|
||||
**Step 2 — Length:**
|
||||
|
||||
> *"How detailed?"*
|
||||
>
|
||||
> **[Quick]** — 1-2 sentences, just the essentials
|
||||
> **[Detailed]** — Full breakdown with steps and findings
|
||||
|
||||
Both steps are single-click. If the engineer triggers via chat with a specific phrase (e.g., "quick update for the client"), both steps are skipped.
|
||||
|
||||
### 3. AI Generates Summary
|
||||
|
||||
Based on the full session context (all messages, steps tried, current diagnosis), AI generates the appropriate summary.
|
||||
|
||||
#### Ticket Notes Mode
|
||||
|
||||
- **Tone:** Technical, concise, factual (customizable per team — see Team Templates below)
|
||||
- **Format:** PSA-compatible markdown (ConnectWise supports markdown in notes)
|
||||
- **Content includes:**
|
||||
- Current status (investigating / identified / implementing fix)
|
||||
- Steps completed and findings
|
||||
- What's been ruled out
|
||||
- Current hypothesis / next steps
|
||||
- Time spent so far
|
||||
|
||||
**Example output (Detailed):**
|
||||
|
||||
```
|
||||
**Status: Investigating**
|
||||
**Time spent: 22 minutes**
|
||||
**Steps completed:**
|
||||
- Verified MX records — correct (pointing to Exchange Online)
|
||||
- Ran message trace in EAC — emails queuing at transport layer
|
||||
- Checked recipient mailbox — not full, no forwarding rules
|
||||
- Reviewed mail flow rules — found suspicious tenant-wide transport rule
|
||||
|
||||
**Current diagnosis:**
|
||||
Transport rule "Block External Senders" appears to be scoped tenant-wide instead of per-group. This is likely blocking all external inbound mail.
|
||||
|
||||
**Next steps:**
|
||||
- Confirm rule scope with client before modifying
|
||||
- Test with a single mailbox first if client approves
|
||||
```
|
||||
|
||||
**Example output (Quick):**
|
||||
|
||||
```
|
||||
Investigating email delivery issue — 22 min in. Traced to a tenant-wide transport rule blocking external senders. Need client approval to modify scope.
|
||||
```
|
||||
|
||||
#### Client Update Mode
|
||||
|
||||
- **Tone:** Professional, reassuring, non-technical (customizable per team — see Team Templates below)
|
||||
- **Format:** Plain text (suitable for portal message or pasting into chat)
|
||||
- **Content includes:**
|
||||
- What we're working on (plain language)
|
||||
- What we've found so far
|
||||
- What we're doing next
|
||||
- Expected next update time (if inferable)
|
||||
- **Content NEVER includes:**
|
||||
- Technical jargon (no "transport rules", "MX records", "EAC")
|
||||
- Server names, IP addresses, internal tool names
|
||||
- Anything that would confuse a non-technical stakeholder
|
||||
- **Client name auto-insertion:** If the session has a client/company from intake fields or PSA ticket context, the update addresses them by name ("Hi Acme Medical Group" not generic "Hi")
|
||||
|
||||
#### Email Draft Mode
|
||||
|
||||
- **Tone:** Same as Client Update but wrapped in full email structure
|
||||
- **Format:** Complete email ready to paste into Outlook/Gmail
|
||||
- **Content includes:**
|
||||
- Subject line (e.g., "Update: Email delivery issue — [Ticket #]")
|
||||
- Greeting with client name (if available)
|
||||
- Body (same content as Client Update)
|
||||
- Professional sign-off with engineer's name (from user profile)
|
||||
- **Use case:** Many MSPs still communicate via email, not PSA portals
|
||||
|
||||
**Example output (Detailed):**
|
||||
|
||||
```text
|
||||
Hi Acme Medical Group,
|
||||
|
||||
We're actively working on the email delivery issue. Here's where we stand:
|
||||
|
||||
We've confirmed that your email system's core settings are correct — the issue isn't with your email addresses or mailboxes. We've traced it to a mail routing configuration that's preventing incoming emails from being delivered.
|
||||
|
||||
We've identified the specific setting that needs to be adjusted and will confirm the change with you before making it. Once approved, we expect delivery to resume within minutes.
|
||||
|
||||
We'll update you again shortly.
|
||||
|
||||
Best regards,
|
||||
Michael
|
||||
```
|
||||
|
||||
**Example output (Quick):**
|
||||
|
||||
```text
|
||||
Hi Acme Medical Group — quick update on the email issue. We've identified the cause and have a fix ready. Just need your approval before making the change. Expect resolution within 15 minutes after that. We'll follow up shortly.
|
||||
```
|
||||
|
||||
**Example output (Email Draft):**
|
||||
|
||||
```text
|
||||
Subject: Update: Email delivery issue — TKT-2847
|
||||
|
||||
Hi Acme Medical Group,
|
||||
|
||||
Just a quick update on the email delivery issue you reported.
|
||||
|
||||
We've completed our investigation and identified the cause — a mail routing configuration is preventing incoming emails from being delivered. We have a fix ready and just need your approval before making the change.
|
||||
|
||||
Once approved, we expect email delivery to resume within minutes.
|
||||
|
||||
Please let us know if you have any questions.
|
||||
|
||||
Best regards,
|
||||
Michael Chihlas
|
||||
ResolutionFlow
|
||||
```
|
||||
|
||||
### 4. Actions After Generation
|
||||
|
||||
The summary appears in the chat as a formatted message with action buttons:
|
||||
|
||||
| Button | Action |
|
||||
| ------ | ------ |
|
||||
| **Copy** | Copy to clipboard (toast: "Copied to clipboard") |
|
||||
| **Post to Ticket** | Push directly to ConnectWise ticket as a note (only visible if PSA connected + ticket linked) |
|
||||
| **Regenerate** | Generate a new version (same audience + length) |
|
||||
| **Switch Audience** | Switch between ticket notes ↔ client update ↔ email draft |
|
||||
| **Switch Length** | Toggle quick ↔ detailed |
|
||||
| **Set Reminder** | Schedule a follow-up reminder (see Follow-up Reminders below) |
|
||||
|
||||
**Post to Ticket details:**
|
||||
|
||||
- Ticket Notes → posted as **Internal Note** (`internalAnalysisFlag: true`)
|
||||
- Client Update → posted as **External Note** (`internalAnalysisFlag: false`) — visible to client in their portal
|
||||
- Uses existing `POST /service/tickets/{id}/notes` ConnectWise endpoint
|
||||
- Uses existing PSA connection and member mapping from the session
|
||||
|
||||
### 5. Multiple Updates Per Session
|
||||
|
||||
Engineers can request status updates multiple times during a session. Each update:
|
||||
|
||||
- Uses the full conversation context up to that point
|
||||
- References what changed since the last update (if applicable)
|
||||
- Gets saved in the session message history (so it's part of the final documentation)
|
||||
|
||||
---
|
||||
|
||||
## Backend Implementation
|
||||
|
||||
### New Endpoint
|
||||
|
||||
```
|
||||
POST /ai-sessions/{session_id}/status-update
|
||||
```
|
||||
|
||||
**Request body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"audience": "ticket_notes" | "client_update"
|
||||
}
|
||||
```
|
||||
|
||||
**Response body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "string — the generated update",
|
||||
"audience": "ticket_notes" | "client_update",
|
||||
"session_status": "investigating" | "identified" | "implementing",
|
||||
"steps_completed": 5,
|
||||
"time_spent_minutes": 22,
|
||||
"generated_at": "2026-03-23T14:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### FlowPilot Engine Addition
|
||||
|
||||
Add `generate_status_update()` to `flowpilot_engine.py`:
|
||||
|
||||
- Loads session + all steps/messages
|
||||
- Builds a status-update-specific system prompt based on audience
|
||||
- Calls the AI model with full conversation context
|
||||
- Returns formatted update
|
||||
|
||||
**System prompt guidance (ticket notes):**
|
||||
|
||||
```
|
||||
You are generating an internal status update for a PSA ticket note.
|
||||
Be technical, concise, and factual. Use markdown formatting.
|
||||
Include: current status, steps completed, findings, what's been ruled out, next steps.
|
||||
Do NOT soften language or add pleasantries.
|
||||
```
|
||||
|
||||
**System prompt guidance (client update):**
|
||||
|
||||
```
|
||||
You are generating a client-facing status update.
|
||||
Be professional, reassuring, and non-technical.
|
||||
NEVER use technical jargon, server names, IP addresses, or internal tool names.
|
||||
Explain findings in plain language a non-technical business owner would understand.
|
||||
Include: what we're working on, what we've found, what's next.
|
||||
Keep it brief — 3-5 short paragraphs maximum.
|
||||
```
|
||||
|
||||
### PSA Push (ConnectWise)
|
||||
|
||||
Reuse existing infrastructure from session resolution:
|
||||
|
||||
- `services/psa/connectwise/client.py` already has `create_ticket_note()`
|
||||
- Add a new helper or reuse existing: `push_status_update_to_psa(session, content, is_internal)`
|
||||
- `internalAnalysisFlag` = `true` for ticket notes, `false` for client updates
|
||||
|
||||
### Data Model
|
||||
|
||||
No new tables needed. Status updates are stored as regular session messages:
|
||||
|
||||
- `ai_session_steps` with `step_type = 'status_update'`
|
||||
- `content` JSONB includes: `{ audience, generated_content, psa_push_status }`
|
||||
|
||||
This keeps updates in the session timeline and they'll appear in the final documentation.
|
||||
|
||||
---
|
||||
|
||||
## Frontend Implementation
|
||||
|
||||
### FlowPilotActionBar Changes
|
||||
|
||||
Add "Share Update" button to the action bar between Escalate and Pause:
|
||||
|
||||
```tsx
|
||||
<button
|
||||
onClick={onShareUpdate}
|
||||
className="flex items-center gap-2 rounded-lg bg-cyan-500/10 border border-cyan-500/20 px-4 py-2 min-h-[44px] text-sm font-medium text-cyan-400 hover:bg-cyan-500/20 transition-colors"
|
||||
>
|
||||
<FileText size={16} />
|
||||
Share Update
|
||||
</button>
|
||||
```
|
||||
|
||||
### StatusUpdateModal Component
|
||||
|
||||
New modal that handles the audience selection + generated output:
|
||||
|
||||
**State 1: Audience Selection**
|
||||
|
||||
- Title: "Share Status Update"
|
||||
- Two large option cards: "Ticket Notes" and "Client Update"
|
||||
- Each card has icon, title, description
|
||||
|
||||
**State 2: Generating**
|
||||
|
||||
- Loading spinner with "Generating update..."
|
||||
- Shows audience selected
|
||||
|
||||
**State 3: Result**
|
||||
|
||||
- Formatted preview of the generated update
|
||||
- Action buttons: Copy, Post to Ticket (conditional), Regenerate, Switch Audience
|
||||
- "Post to Ticket" only visible when `hasPsaTicket` is true
|
||||
|
||||
### Chat Integration
|
||||
|
||||
When triggered via chat (engineer types "status update"):
|
||||
|
||||
- FlowPilot detects the intent in the normal message flow
|
||||
- Responds with audience selection buttons inline (same as existing action buttons pattern)
|
||||
- After selection, generates and displays the update in the chat stream
|
||||
- Copy/Post to Ticket buttons appear below the update message
|
||||
|
||||
### API Client
|
||||
|
||||
Add to `frontend/src/api/aiSessions.ts`:
|
||||
|
||||
```typescript
|
||||
generateStatusUpdate: (sessionId: string, audience: 'ticket_notes' | 'client_update') =>
|
||||
apiClient.post(`/ai-sessions/${sessionId}/status-update`, { audience })
|
||||
```
|
||||
|
||||
### Hook Extension
|
||||
|
||||
Add to `useFlowPilotSession`:
|
||||
|
||||
```typescript
|
||||
generateStatusUpdate: async (audience: 'ticket_notes' | 'client_update') => {
|
||||
const result = await aiSessionsApi.generateStatusUpdate(sessionId, audience)
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Chat Intent Detection
|
||||
|
||||
Add status update detection to the FlowPilot engine's intent recognition:
|
||||
|
||||
**Trigger phrases:**
|
||||
|
||||
- "status update"
|
||||
- "give me an update"
|
||||
- "share progress"
|
||||
- "write a summary"
|
||||
- "update for the ticket"
|
||||
- "update for the client"
|
||||
- "what should I tell the client"
|
||||
- "ticket note"
|
||||
|
||||
If the phrase specifies audience and/or length (e.g., "quick update for the client"), skip those steps and generate directly.
|
||||
|
||||
---
|
||||
|
||||
## Team Communication Templates
|
||||
|
||||
Team admins can customize the default tone and format for status updates via Account Settings → Communication Templates.
|
||||
|
||||
### Configurable settings
|
||||
|
||||
| Setting | Options | Default |
|
||||
| ------- | ------- | ------- |
|
||||
| Client tone | Professional, Friendly, Formal | Professional |
|
||||
| Client sign-off | Custom text or auto (engineer name) | Auto |
|
||||
| Company name in sign-off | Include / Exclude | Include |
|
||||
| Ticket notes format | Markdown, Plain text | Markdown |
|
||||
| Default length | Quick, Detailed | Detailed |
|
||||
|
||||
### Tone examples
|
||||
|
||||
**Professional (default):**
|
||||
> "We've identified the cause and have a fix ready."
|
||||
|
||||
**Friendly:**
|
||||
> "Good news — we've found what's causing this and we're ready to fix it!"
|
||||
|
||||
**Formal:**
|
||||
> "We wish to inform you that we have completed our investigation and identified the root cause of the reported issue."
|
||||
|
||||
### Storage
|
||||
|
||||
Templates stored in `accounts` table as JSONB column `communication_templates`:
|
||||
|
||||
```json
|
||||
{
|
||||
"client_tone": "professional",
|
||||
"client_signoff": "auto",
|
||||
"include_company_in_signoff": true,
|
||||
"ticket_notes_format": "markdown",
|
||||
"default_length": "detailed"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Follow-up Reminders
|
||||
|
||||
After generating a status update, the engineer can set a reminder to send another one.
|
||||
|
||||
### Flow
|
||||
|
||||
1. After update is generated, "Set Reminder" button appears
|
||||
2. Quick options: **15 min**, **30 min**, **1 hour**, **Custom**
|
||||
3. When the timer fires:
|
||||
- In-app notification: *"Time to send another update to [Client Name] on the email delivery issue"*
|
||||
- Click notification → opens the session with the Share Update modal pre-loaded
|
||||
5. If the session was resolved before the reminder fires, auto-dismiss with a note: *"Reminder cancelled — session resolved"*
|
||||
|
||||
### Storage
|
||||
|
||||
Reminders stored as `ai_session_steps` with `step_type = 'update_reminder'`:
|
||||
|
||||
```json
|
||||
{
|
||||
"remind_at": "2026-03-23T15:00:00Z",
|
||||
"audience": "client_update",
|
||||
"status": "pending" | "fired" | "cancelled"
|
||||
}
|
||||
```
|
||||
|
||||
Checked via existing APScheduler interval job or a lightweight frontend timer (for v1, frontend `setTimeout` is sufficient since the session is active).
|
||||
|
||||
---
|
||||
|
||||
## Update History Sidebar
|
||||
|
||||
A mini-timeline in the session sidebar showing all status updates sent during the session.
|
||||
|
||||
### What it shows
|
||||
|
||||
Each entry displays:
|
||||
|
||||
- **Audience icon:** clipboard (ticket), user (client), mail (email draft)
|
||||
- **Timestamp:** "2:15 PM"
|
||||
- **Length badge:** "Quick" or "Detailed"
|
||||
- **Delivery status:** Copied / Posted to ticket / Pending reminder
|
||||
- **Click to expand:** Shows the full generated text
|
||||
|
||||
### Location
|
||||
|
||||
Inside the existing session sidebar (right side of FlowPilot), below the session info section. Collapsible: "Updates (3)" header that expands to show the timeline.
|
||||
|
||||
### Why this matters
|
||||
|
||||
Engineers lose track of what they've already communicated, especially on long sessions. This prevents duplicate updates and lets them reference what they told the client earlier.
|
||||
|
||||
---
|
||||
|
||||
## Resolution Communication
|
||||
|
||||
The same audience/length system applies when an engineer **resolves** a session — this is where it matters most.
|
||||
|
||||
### Enhanced Resolve Flow
|
||||
|
||||
**Current flow:**
|
||||
|
||||
1. Engineer clicks Resolve → types summary → auto-generated documentation → done
|
||||
|
||||
**Enhanced flow:**
|
||||
|
||||
1. Engineer clicks Resolve → types summary → auto-generated documentation
|
||||
2. **"Share Resolution"** step appears immediately after, with the same options:
|
||||
- Audience: Ticket Notes / Client Update / Email Draft
|
||||
- Length: Quick / Detailed
|
||||
3. Pre-generated based on team's default settings (no extra clicks if defaults are right)
|
||||
4. Engineer can Copy, Post to Ticket, or skip
|
||||
|
||||
### Resolution-Specific Content
|
||||
|
||||
#### Ticket Notes (Resolution)
|
||||
|
||||
```text
|
||||
**Status: Resolved**
|
||||
**Time spent: 35 minutes**
|
||||
**Root cause: Tenant-wide transport rule blocking external senders**
|
||||
|
||||
**Investigation steps:**
|
||||
- Verified MX records — correct
|
||||
- Ran message trace — emails queuing at transport layer
|
||||
- Checked recipient mailbox — no issues
|
||||
- Identified transport rule "Block External" scoped tenant-wide instead of per-group
|
||||
|
||||
**Resolution:**
|
||||
Modified transport rule scope from tenant-wide to security group "External-Block-Group". Verified mail flow resumed within 5 minutes. Confirmed with end user that emails are now being received.
|
||||
|
||||
**Recommendations:**
|
||||
- Review all tenant-wide transport rules quarterly
|
||||
- Document rule changes in change management system
|
||||
```
|
||||
|
||||
#### Client Update (Resolution)
|
||||
|
||||
```text
|
||||
Hi Acme Medical Group,
|
||||
|
||||
Great news — the email delivery issue is resolved.
|
||||
|
||||
We found that a mail routing setting was preventing incoming emails from being delivered to your mailboxes. We've corrected the configuration, and email delivery has been confirmed working.
|
||||
|
||||
If you or your team notice any further issues with email, please don't hesitate to reach out.
|
||||
|
||||
Best regards,
|
||||
Michael
|
||||
```
|
||||
|
||||
#### Email Draft (Resolution)
|
||||
|
||||
```text
|
||||
Subject: Resolved: Email delivery issue — TKT-2847
|
||||
|
||||
Hi Acme Medical Group,
|
||||
|
||||
I'm happy to report that the email delivery issue has been resolved.
|
||||
|
||||
The cause was a mail routing configuration that was blocking incoming emails. We've corrected this, and your team should now be receiving emails normally. We verified delivery is working before closing the ticket.
|
||||
|
||||
If you notice any further issues, please let us know and we'll investigate immediately.
|
||||
|
||||
Best regards,
|
||||
Michael Chihlas
|
||||
ResolutionFlow
|
||||
```
|
||||
|
||||
### How It Integrates
|
||||
|
||||
- Reuses the exact same `generate_status_update()` backend function, with an additional `context: "resolution"` parameter
|
||||
- The resolution summary the engineer typed feeds into the generation as the authoritative "what fixed it"
|
||||
- The existing resolve endpoint (`POST /ai-sessions/{id}/resolve`) returns documentation as before, but now the frontend shows the "Share Resolution" step after
|
||||
- If ConnectWise is connected, "Post to Ticket" pushes the resolution note alongside the existing auto-documentation push
|
||||
|
||||
### Escalation Communication
|
||||
|
||||
Same system for escalations — when an engineer escalates, offer:
|
||||
|
||||
- **Ticket Notes:** Technical handoff note (what was tried, what failed, why it's being escalated)
|
||||
- **Client Update:** "We're bringing in a specialist to look at this more closely..."
|
||||
- **Email Draft:** Full email with escalation context
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Core (implement now)
|
||||
|
||||
1. **Backend:** `generate_status_update()` in `flowpilot_engine.py` + endpoint in `ai_sessions.py`
|
||||
2. **Frontend:** `StatusUpdateModal` with 2-step selection (audience + length) + "Share Update" button in action bar
|
||||
3. **Three audiences:** Ticket Notes, Client Update, Email Draft
|
||||
4. **Two lengths:** Quick and Detailed
|
||||
5. **Copy to clipboard** functionality
|
||||
6. **Client name auto-insertion** from intake fields or PSA ticket context
|
||||
7. **Store as session step** (`step_type = 'status_update'`)
|
||||
8. **Resolution communication** — "Share Resolution" step after resolve, same audience/length options
|
||||
9. **Escalation communication** — "Share Escalation" step after escalate, same options
|
||||
|
||||
### Phase 2: Update History + Reminders
|
||||
|
||||
1. **Update history sidebar** — mini-timeline of all updates/resolutions sent during session
|
||||
2. **Follow-up reminders** — set timer after sending update, in-app notification when it fires
|
||||
3. **Auto-dismiss reminders** when session resolves before timer
|
||||
|
||||
### Phase 3: Team Templates
|
||||
|
||||
1. **Communication Templates** in Account Settings — tone, sign-off, format preferences
|
||||
2. **Template-aware generation** — system prompts incorporate team's configured tone/style
|
||||
|
||||
### Phase 4: PSA Push (implement with ConnectWise integration)
|
||||
|
||||
1. **Post to Ticket** button — push to ConnectWise as internal or external note
|
||||
2. **PSA status indicator** — show success/failure after push
|
||||
|
||||
### Phase 5: Chat Integration (polish)
|
||||
|
||||
1. **Intent detection** — recognize status update requests in natural language
|
||||
2. **Inline generation** — audience buttons + update rendered in chat stream
|
||||
3. **"Since last update" awareness** — reference changes since previous status update
|
||||
4. **Shorthand commands** — "quick update for the client" skips both selection steps
|
||||
|
||||
---
|
||||
|
||||
## Edge Cases
|
||||
|
||||
- **No messages yet:** Disable "Share Update" until at least 2 message exchanges
|
||||
- **Session paused/resolved:** Still allow generating updates (useful for post-session documentation)
|
||||
- **No PSA connected:** Hide "Post to Ticket" button, only show Copy
|
||||
- **PSA push fails:** Show error toast, keep the generated content available for manual copy
|
||||
- **Multiple rapid requests:** Debounce — disable button for 3 seconds after generation
|
||||
- **Very short session:** AI should still produce a useful update, even if minimal ("Currently investigating — gathering initial information")
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- % of sessions where "Share Update" is used (target: 30%+ of sessions >10 minutes)
|
||||
- Time between update generation and ticket note creation (should be <5 seconds with Post to Ticket)
|
||||
- Net Promoter feedback on update quality (post-pilot survey)
|
||||
Reference in New Issue
Block a user