Action Workspace & AI Briefings
The action workspace replaces the default dashboard landing with an AI-driven view that surfaces what matters most. It generates prioritized briefings, suggests concrete actions, and provides deep-dive analysis — all updated daily at 5am local time.
Overview
Section titled “Overview”When you open the dashboard (/), the WorkspaceView loads five resources in parallel:
- Workspace summary — badge counts for unanswered messages, overdue tasks, today’s tasks, and missed calls
- Needs attention — detailed lists behind each badge
- AI briefing — cached summary with ranked actions
- Detailed analysis — agentic deep-dive with entity-linked sections
- Engagement stats — recent activity feed
Each section renders independently with skeleton states — no waterfall.
Data Model
Section titled “Data Model”DashboardBriefing
Section titled “DashboardBriefing”pub struct DashboardBriefing { pub briefing_text: String, // Markdown with bold highlights pub actions: Vec<BriefingAction>, pub generated_at: String, // Formatted in org timezone}
pub struct BriefingAction { pub priority: String, // "urgent" | "high" | "normal" pub action_type: String, // "follow_up" | "reply" | "return_call" | "complete_task" | "reconnect" pub title: String, pub reason: String, pub contact_id: Option<Uuid>, pub task_id: Option<Uuid>, pub call_id: Option<Uuid>, pub suggested_actions: Vec<String>, // ["call", "message", "done", "open", "reply"]}DashboardDetailedBriefing
Section titled “DashboardDetailedBriefing”pub struct DashboardDetailedBriefing { pub detailed_text: String, // Markdown with ## sections per contact pub mentioned_contacts: Vec<MentionedContact>, pub generated_at: String,}
pub struct MentionedContact { pub contact_id: Uuid, pub name: String, pub section_title: String, pub urgency: String, // "urgent" | "high" | "normal"}WorkspaceSummary
Section titled “WorkspaceSummary”pub struct WorkspaceSummary { pub unanswered_count: u32, pub overdue_tasks_count: u32, pub today_tasks_count: u32, pub missed_calls_count: u32,}WorkspaceNeedsAttention
Section titled “WorkspaceNeedsAttention”pub struct WorkspaceNeedsAttention { pub overdue_tasks: Vec<WorkspaceTask>, pub today_tasks: Vec<WorkspaceTask>, pub unanswered_contacts: Vec<WorkspaceUnansweredContact>, pub missed_calls: Vec<WorkspaceMissedCall>,}Each list returns up to 20 items with entity references (contact IDs, task IDs, call IDs) for linking.
API Endpoints
Section titled “API Endpoints”| Method | Path | Description |
|---|---|---|
GET | /api/dashboard/workspace-summary | Badge counts |
GET | /api/dashboard/workspace-needs-attention | Detailed lists behind badges |
GET | /api/dashboard/briefing | Cached AI briefing (returns null if not yet generated) |
POST | /api/dashboard/briefing/generate | Trigger fresh AI briefing generation |
GET | /api/dashboard/detailed-briefing | Cached detailed analysis |
POST | /api/dashboard/detailed-briefing/generate | Trigger agentic deep-dive (requires briefing to exist) |
All endpoints enforce permissions via resolve_dashboard_scope(). Users without messaging permissions see unanswered_count: 0 instead of an error.
AI Briefing Generation
Section titled “AI Briefing Generation”Summary Briefing
Section titled “Summary Briefing”generate_dashboard_briefing collects context, sends it to an LLM, and upserts the result:
- Collect context —
collect_briefing_context()gathers the top 10 unanswered contacts, overdue tasks, today’s tasks, missed calls (last 7 days), and contacts going cold (7+ days since last contact) - Build prompt — system prompt instructs the LLM to produce a markdown summary with 5–8 ranked actions
- Generate — calls
generate_text()with structured output schemaBriefingOutput - Upsert — stores in
dashboard_briefingtable using a unique index onmember_id - Track usage — logs via
spawn_log_ai_usage(AiUsageFeature::DashboardBriefing)
Actions are ranked by priority:
- Urgent — overdue items, 24h+ unanswered messages
- High — due today, 7+ days since last contact
- Normal — routine follow-ups
Detailed Analysis
Section titled “Detailed Analysis”generate_detailed_briefing performs an agentic investigation using read-only tools:
- Load prerequisites — requires a summary briefing to exist (returns error otherwise)
- Build tool set —
get_bulk_contact_memory,get_bulk_contact_messages,get_call_details,get_contact_details,get_tasks - Investigate — LLM uses tools (max 10 steps) to deep-dive the top 3–5 contacts
- Entity linking — every contact, task, and call in the output is a markdown link:
[Name](/contacts/{id}) - Upsert — stores in
dashboard_detailed_briefingtable
Scheduled Generation
Section titled “Scheduled Generation”GenerateScheduledBriefingsJob runs every hour (cron: 0 0 * * * * *) and generates briefings at 5am local time per organization.
Flow:
- Find organizations with members active in the last 3 days
- Batch-fetch org timezones from
organization_profile - For each org where the local hour is 5am:
- Fetch active members and their permissions
- Skip members who already have a briefing generated today
- Build a synthetic
SessionviaSession::from_models() - Call
generate_dashboard_briefing()per member
Failures are isolated — one member’s error doesn’t block others.
// Key constantsconst BRIEFING_TARGET_HOUR: u32 = 5; // 5am local timeconst ACTIVE_DAYS: i64 = 3; // Only active membersDatabase Tables
Section titled “Database Tables”Two tables with upsert semantics via unique indexes on member_id:
dashboard_briefing — briefing_text (text), actions_json (jsonb), generated_at (timestamptz), FK to member and organization
dashboard_detailed_briefing — detailed_text (text), mentioned_contacts_json (jsonb, default []), generated_at (timestamptz), FK to member and organization
Both use ON CONFLICT (member_id) update semantics — each member has at most one row that gets overwritten on regeneration.
UI Components
Section titled “UI Components”AiBriefingCard
Section titled “AiBriefingCard”Renders three states:
- Generating — skeleton animation
- Empty — CTA button “Get your AI briefing”
- Loaded — gradient card with markdown briefing, relative timestamp, and refresh button
Actions display in a grouped list by priority (Urgent → High → Follow Up). Each action row shows the title, reason, and inline buttons based on suggested_actions (call, message, done, open, reply).
DetailedAnalysisCard
Section titled “DetailedAnalysisCard”Collapsible card with:
- Quick-links bar — urgency-colored badges for mentioned contacts
- Markdown content — entity-linked sections per contact with
## [Name](/contacts/{id}) — Situationheadings - SPA navigation —
intercept_markdown_links()hooks click events on entity links to prevent full page reloads
Requires a summary briefing before generation. Shows a disabled CTA if no summary exists.
WorkspaceNeedsAttentionSection
Section titled “WorkspaceNeedsAttentionSection”Collapsible section with four tabs: overdue tasks, today’s tasks, unanswered contacts, and missed calls. Each tab shows a list with entity links and action buttons.
Module Structure
Section titled “Module Structure”src/mods/dashboard/├── api/│ ├── get_workspace_summary_api.rs│ ├── get_workspace_needs_attention_api.rs│ ├── get_dashboard_briefing_api.rs│ ├── generate_dashboard_briefing_api.rs│ ├── get_dashboard_detailed_briefing_api.rs│ └── generate_dashboard_detailed_briefing_api.rs├── components/│ ├── ai_briefing_card_component.rs│ ├── detailed_analysis_card_component.rs│ ├── workspace_greeting_component.rs│ ├── workspace_needs_attention_component.rs│ ├── quick_actions_component.rs│ └── recent_activity_feed_component.rs├── jobs/│ └── generate_scheduled_briefings_job.rs├── services/│ ├── collect_briefing_context_service.rs│ ├── generate_dashboard_briefing_service.rs│ ├── generate_detailed_briefing_service.rs│ ├── generate_scheduled_briefings_service.rs│ ├── get_workspace_summary_service.rs│ └── get_workspace_needs_attention_service.rs├── types/│ ├── dashboard_briefing_type.rs│ ├── dashboard_detailed_briefing_type.rs│ ├── workspace_summary_type.rs│ └── workspace_needs_attention_type.rs└── views/ └── workspace_view.rsRelated Pages
Section titled “Related Pages”- Dashboard Analytics — KPIs, charts, and heatmaps
- AI Services — model configuration and text generation
- AI Usage Tracking — cost and token logging
- Timezone Support — org timezone handling