Dashboard 2.0 Components Guide
Multi-Project, Multi-Tenant, Multi-Team Navigation System
Version: 2.0 Date: November 27, 2025 Status: Production Specification
Table of Contents
- Overview
- Component Architecture
- Data Sources
- Role-Based Views
- Multi-Tenant Architecture
- Component Reference
- Integration Guide
Overview
Purpose
Dashboard 2.0 provides GPS navigation for agentic work across multiple projects, teams, tenants, and git repositories. The system answers five critical questions in < 5 seconds without scrolling:
- Which project needs attention? → Project Summary Bar
- What tasks are in progress? → Kanban Board
- What is blocking progress? → Blocker Panel
- What completed recently? → Activity Feed
- Am I on track? → Progress Visualization
Design Philosophy: GPS Not Engine
Traditional Dashboard (Engine Diagnostics):
- Message counts, token usage, session duration
- "How is the engine working?"
- Machinery-focused metrics
Dashboard 2.0 (GPS Navigation):
- Task progress, blockers, route to completion
- "Where am I going and what's in the way?"
- Journey-focused intelligence
Core Principles
- Exception-Based Display - Only show deviations from baseline
- Task-Centric Architecture - Checkbox is source of truth
- Three-Level Hierarchy - Primary view, drill-down, deep inspection
- Multi-Project Awareness - Navigate across entire portfolio
- Real-Time Updates - WebSocket-powered live data
Component Architecture
System Overview
┌─────────────────────────────────────────────────────────┐
│ Dashboard 2.0 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─ LEVEL 1: Primary View (Non-Scrolling) ──────────┐ │
│ │ │ │
│ │ • Project Summary Bar (all projects) │ │
│ │ • Multi-Project Selector (modal) │ │
│ │ • Task Kanban Board (selected project) │ │
│ │ • Activity Feed (5 items max) │ │
│ │ • Blocker Panel (exception-based) │ │
│ │ • Work Distribution Chart (this week) │ │
│ │ │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ ┌─ LEVEL 2: Drill-Down (On-Demand) ──────────────┐ │
│ │ │ │
│ │ • Full task list with filters │ │
│ │ • Commit timeline │ │
│ │ • Session summaries │ │
│ │ • Progress burndown │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─ LEVEL 3: Deep Inspection (Hidden) ───────────┐ │
│ │ │ │
│ │ • Session message history │ │
│ │ • Commit diffs │ │
│ │ • Task change history │ │
│ │ • Raw activity logs │ │
│ │ │ │
│ └────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Component Hierarchy
Dashboard Container
├── Header
│ ├── Logo & Title
│ ├── Multi-Project Selector
│ └── User Settings
│
├── Project Summary Bar
│ ├── Project Card (repeating)
│ │ ├── Name + Blocker Indicator
│ │ ├── Progress Bar
│ │ ├── Stats (tasks, commits, last active)
│ │ └── Velocity Indicator
│ └── Create New Project Button
│
├── Main Content Grid (2-column)
│ │
│ ├── Left Column: Task Journey
│ │ └── Kanban Board
│ │ ├── Pending Column
│ │ ├── In Progress Column (with blocked tasks)
│ │ ├── Review Column
│ │ └── Done Column
│ │ └── Task Card (repeating)
│ │ ├── Checkbox
│ │ ├── Title + Complexity Badge
│ │ ├── Progress Bar (if in progress)
│ │ ├── Evidence (commits, sessions)
│ │ └── Blocked Badge (if blocked)
│ │
│ └── Right Column: Intelligence Panel
│ ├── Activity Feed (max 5 items)
│ │ └── Activity Item (repeating)
│ │ ├── Icon (type indicator)
│ │ ├── Description
│ │ ├── Evidence
│ │ └── Timestamp
│ │
│ └── Blocker Panel (exception-based)
│ └── Blocker Card (repeating)
│ ├── Task Title
│ ├── Blocked Reason
│ ├── Days Blocked
│ └── Action Buttons
│
└── Footer Dashboard
└── Work Distribution Chart
└── Project Bar (repeating)
├── Project Name
├── Weighted Bar
├── Percentage
└── Details (commits, sessions, tasks)
Data Sources
Primary Data Entities
1. Projects
projects
├── id (UUID)
├── tenant_id (UUID) -- Multi-tenant isolation
├── name (VARCHAR)
├── repository_url (VARCHAR)
├── category (VARCHAR) -- cloud, dev, ops, etc.
└── status (VARCHAR) -- active, on-hold, completed
Source: projects table
Refresh: Real-time via WebSocket
Used By: Project Summary Bar, Multi-Project Selector, Work Distribution
2. Tasks
tasks
├── id (UUID)
├── project_id (UUID)
├── title (VARCHAR)
├── checked (BOOLEAN) -- ⭐ SOURCE OF TRUTH
├── status (VARCHAR) -- pending, in_progress, review, blocked, done
├── complexity (VARCHAR) -- S, M, L, XL
├── blocked_reason (TEXT) -- Only if status='blocked'
├── priority (VARCHAR) -- P0, P1, P2, P3
└── assigned_to (UUID) -- Multi-user support
Source: tasks table
Refresh: Real-time via WebSocket on task updates
Used By: Kanban Board, Activity Feed, Blocker Panel, Progress Calculation
3. Git Commits
git_commits
├── sha (VARCHAR)
├── repo_id (UUID)
├── message (TEXT)
├── author (VARCHAR)
├── timestamp (TIMESTAMP)
├── additions (INTEGER)
└── deletions (INTEGER)
-- Linking table with confidence scores
task_commit_links
├── task_id (UUID)
├── commit_sha (VARCHAR)
├── confidence (DECIMAL 0.0-1.0)
├── link_type (explicit | inferred)
└── evidence (TEXT)
Source: Git repository integrations Refresh: On git push events (webhooks) Used By: Activity Feed, Task Cards (evidence), Work Distribution
4. LLM Sessions
llm_sessions
├── id (UUID)
├── project_id (UUID)
├── started_at (TIMESTAMP)
├── ended_at (TIMESTAMP)
├── message_count (INTEGER)
├── summary (TEXT)
└── agent_type (VARCHAR) -- Which CODITECT agent
-- Linking table with confidence scores
task_session_links
├── task_id (UUID)
├── session_id (UUID)
├── confidence (DECIMAL 0.0-1.0)
├── link_type (explicit | inferred)
└── evidence (TEXT)
Source: CODITECT agentic session tracking Refresh: On session end Used By: Activity Feed, Task Cards (evidence), Work Distribution
5. Teams & Tenants
tenants
├── id (UUID)
├── name (VARCHAR)
├── plan_tier (VARCHAR) -- starter, professional, enterprise
└── max_projects (INTEGER)
teams
├── id (UUID)
├── tenant_id (UUID)
├── name (VARCHAR)
└── permissions (JSONB)
team_members
├── user_id (UUID)
├── team_id (UUID)
├── role (VARCHAR) -- viewer, developer, admin
└── permissions (JSONB) -- Granular overrides
Source: tenants, teams, team_members tables
Refresh: On user/team changes
Used By: Multi-tenant filtering, role-based permissions, project visibility
Role-Based Views
Viewer Role
Permissions:
- ✅ View all projects (within tenant)
- ✅ View tasks and progress
- ✅ View activity feed
- ❌ Cannot edit tasks
- ❌ Cannot create projects
- ❌ Cannot resolve blockers
Dashboard Display:
- All components visible (read-only)
- No action buttons shown
- Progress indicators and charts available
- Drill-down to details available
Developer Role
Permissions:
- ✅ Everything Viewer has
- ✅ Edit tasks (check/uncheck, update status)
- ✅ Link commits to tasks
- ✅ Comment on blockers
- ❌ Cannot create/delete projects
- ❌ Cannot manage team members
Dashboard Display:
- All components with edit capabilities
- Task checkboxes are interactive
- "Resolve" buttons on blockers
- Can update task complexity/status
Admin Role
Permissions:
- ✅ Everything Developer has
- ✅ Create/delete projects
- ✅ Manage team members
- ✅ Configure integrations
- ✅ Access cross-tenant analytics (if super admin)
Dashboard Display:
- Full control over all components
- "Create New Project" button visible
- Team management panel available
- Advanced settings accessible
Multi-Tenant Architecture
Tenant Isolation
Every data query includes tenant filtering:
-- Example: Get projects for current user's tenant
SELECT p.*
FROM projects p
WHERE p.tenant_id = :current_tenant_id
AND p.status = 'active'
ORDER BY p.name;
Key Principles:
- Data Isolation: No cross-tenant data leakage
- URL Scoping:
/tenant/{tenant_id}/dashboard - API Keys: Tenant-specific authentication
- WebSocket Channels: Tenant-scoped subscriptions
Multi-Project Navigation
Project Selector Component:
- Lists ALL projects within current tenant
- Grouped by category (cloud, dev, ops, etc.)
- Filterable by status (active, blocked, done)
- Searchable by name
- Shows mini progress indicator per project
Switching Projects:
- User clicks "All Projects" dropdown
- Modal opens with full project list
- User selects project or searches
- Dashboard reloads data for selected project
- URL updates:
/tenant/{id}/projects/{project_id}/dashboard
Multi-Team Support
Team-Based Filtering:
- Each user belongs to one or more teams
- Teams have assigned projects
- Dashboard shows only projects user's teams can access
- Permissions are team + role based
Example:
- User: Jane (Developer role)
- Teams: Frontend Team, API Team
- Projects Visible: User Dashboard, Payment Gateway API
- Projects Hidden: DevOps Pipeline (Ops Team only)
Component Reference
1. Project Summary Bar
Purpose: High-level overview of ALL projects in tenant
Visual:
Data Sources:
projectstable (name, status)taskstable (aggregated progress)git_commitstable (commit count last 7 days)task_commit_linkstable (last commit time)
Display Elements:
- Project Name
- Blocker Indicator (red dot if any task.status='blocked')
- Progress Bar (green fill = % of tasks.checked=true)
- Stats:
- Tasks completed/total (e.g., "7/12 tasks")
- Commits last 7 days (e.g., "3 commits")
- Last activity time (e.g., "2h ago")
- Velocity Indicator:
- ↗ +N% (tasks completed this week vs last week)
- → 0% (no change)
- ↘ -N% (slower than last week)
Interactions:
- Click project → Navigate to that project's detail dashboard
- Hover → Show tooltip with subtask details
Responsive Behavior:
- Desktop: Horizontal scroll if > 3 projects
- Tablet: 2-column grid
- Mobile: Vertical stack
2. Multi-Project Selector (Modal)
Purpose: Navigate between projects with advanced filtering
Visual:
Data Sources:
projectstable (all accessible projects)teamstable (user's team memberships)taskstable (progress aggregation)git_commitstable (activity indicators)
Display Elements:
- Search Box (live filter by project name)
- Filter Tabs:
- All (count)
- Active (count)
- Blocked (count)
- Done (count)
- Project List (grouped by category):
- Project name
- Progress bar
- Stats (tasks, commits, blockers)
- Velocity trend
- Action Buttons:
- "Create New Project" (if admin)
- "View All" (opens full project management)
Interactions:
- Type in search → Filter list in real-time
- Click filter tab → Show only matching projects
- Click project → Select and close modal
- Click "Create New Project" → Open project wizard
Permissions:
- Viewer: Can view and select
- Developer: Same as viewer
- Admin: Can create new projects
3. Kanban Board
Purpose: Task journey visualization for selected project
Visual: See Portfolio Overview diagram (left column)
Data Sources:
taskstable (filtered by project_id)task_commit_linkstable (evidence count)task_session_linkstable (evidence count)
Columns:
- Pending (status='pending')
- In Progress (status='in_progress')
- Review (status='review')
- Done (status='done', checked=true)
Task Card Elements:
- ☐/☑ Checkbox (interactive if developer+)
- Title
- Complexity Badge (S/M/L/XL color-coded)
- Progress Bar (if in_progress, shows % complete)
- Evidence Line: "N commits • M sessions"
- Blocked Badge (orange border if status='blocked')
Interactions:
- Click checkbox → Toggle task.checked
- Drag task → Move between columns (updates status)
- Click task → Open task detail modal (Level 2)
- Click evidence → Show linked commits/sessions (Level 3)
Blocked Task Display:
- Orange border around card
- "⚠ BLOCKED" badge at top
- Shows days blocked
- Shows blocker reason (truncated)
Real-Time Updates:
- WebSocket event:
task.updated→ Refresh card - WebSocket event:
task.completed→ Move to Done column - WebSocket event:
task.blocked→ Add orange border
4. Activity Feed
Purpose: Top 5 prioritized events from last 24 hours
Visual: See Portfolio Overview diagram (right column, top)
Data Sources:
taskstable (completed, blocked events)git_commitstable (new commits)llm_sessionstable (recent sessions)
Prioritization Algorithm:
PRIORITY_WEIGHTS = {
'task_completed': 100,
'task_blocked': 90,
'commit': 50,
'session': 30,
}
# Calculate score for each event
events = []
for event in all_events_last_24h:
score = PRIORITY_WEIGHTS[event.type]
if event.type == 'commit':
score += (event.additions + event.deletions) / 10 # Bonus for large commits
events.append((score, event))
# Sort by score desc, take top 5
top_5 = sorted(events, reverse=True)[:5]
Activity Item Types:
-
Task Completed (✓ green circle)
- Title: "✓ [Task Name] complete"
- Evidence: "N commits, M sessions"
- Time: "2h ago"
-
Task Blocked (⚠ orange circle)
- Title: "⚠ [Task Name] blocked"
- Reason: "Awaiting API spec"
- Time: "3h ago"
-
Commit (⎇ blue circle)
- Title: "⎇ [sha]: [message]"
- Stats: "+45/-12 lines"
- Time: "4h ago"
-
Session (💬 purple circle)
- Title: "💬 [Summary or task discussed]"
- Time: "6h ago"
Exception Rule:
- If no events in last 24h → Show "No recent activity"
- Max 5 items (STRICT LIMIT per ADR-007)
5. Blocker Panel
Purpose: Exception-based alert for blocked tasks
Visual: See Portfolio Overview diagram (right column, bottom)
Data Sources:
taskstable WHERE status='blocked'task_commit_linkstable (show when last worked on)
Display Elements:
-
Panel Header:
- Orange/amber styling for urgency
- "⚠ Attention Required"
- Count of blockers
-
Blocker Cards (one per blocked task):
- Task title
- Blocked reason (from tasks.blocked_reason)
- Days blocked (calculated from last status change)
- Project name (if viewing portfolio)
- Action buttons:
- "View Task" → Open task detail modal
- "Resolve" → Mark as in_progress
Exception-Based Logic:
# Only show if blockers exist
blockers = tasks.filter(status='blocked')
if not blockers:
# Panel shows: "No blockers 🎉"
# Or hide panel completely
else:
# Show panel with blocker cards
display_blocker_panel(blockers)
Sorting:
- Days blocked DESC (longest blocked first)
- Then by priority (P0 > P1 > P2 > P3)
Real-Time Updates:
- WebSocket event:
task.blocked→ Add to panel - WebSocket event:
task.unblocked→ Remove from panel
6. Work Distribution Chart
Purpose: Show effort allocation across projects (this week)
Visual:
Data Sources:
git_commitstable (last 7 days)llm_sessionstable (last 7 days)taskstable WHERE checked=true (last 7 days)
Calculation:
# Weighted scoring
for project in projects:
commits_this_week = count_commits(project, last_7_days)
sessions_this_week = count_sessions(project, last_7_days)
tasks_this_week = count_tasks_completed(project, last_7_days)
project_score = (
commits_this_week * 3 +
sessions_this_week * 1 +
tasks_this_week * 5
)
# Calculate percentages
total_score = sum(project_score for all projects)
for project in projects:
percentage = (project_score / total_score) * 100
Display Elements:
-
Project Bars (sorted by score DESC):
- Project name
- Horizontal bar (width = percentage)
- Percentage value
- Details: "N commits • M sessions • X tasks"
-
Legend:
- Shows weighting formula
- Total score across all projects
- Time period (e.g., "Nov 20-27, 2025")
Purpose:
- Identify over-allocated projects
- Spot under-utilized projects
- Balance team workload
Integration Guide
API Endpoints
Portfolio Overview:
GET /api/v1/tenants/{tenant_id}/dashboard
Response: {
projects: ProjectSummary[],
kanban: KanbanBoard,
activity: ActivityHighlight[],
blockers: BlockerCard[],
work_distribution: WorkDistribution
}
Multi-Project Selector:
GET /api/v1/tenants/{tenant_id}/projects?category=cloud&status=active
Response: {
projects: Project[],
categories: string[],
filters: FilterOptions
}
Kanban Board:
GET /api/v1/projects/{project_id}/kanban
Response: {
pending: Task[],
in_progress: Task[],
review: Task[],
done: Task[]
}
Task Update:
PATCH /api/v1/tasks/{task_id}
Body: {
checked?: boolean,
status?: string,
blocked_reason?: string
}
Response: Task
WebSocket Events
Subscribe to Project:
ws.send({
type: 'subscribe',
project_ids: ['proj-1', 'proj-2', 'proj-3']
});
Receive Updates:
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case 'task.updated':
updateKanbanCard(msg.task_id, msg.changes);
break;
case 'task.completed':
moveToColumn(msg.task_id, 'done');
refreshProgressBar(msg.project_id);
break;
case 'task.blocked':
addBlockerCard(msg.task_id, msg.blocked_reason);
break;
case 'progress.changed':
updateProgressBar(msg.project_id, msg.progress_pct);
break;
}
};
Multi-Tenant Headers
All API requests must include:
Authorization: Bearer {jwt_token}
X-Tenant-ID: {tenant_id}
Backend validates:
@require_auth
@require_tenant
def get_dashboard(request, tenant_id):
# Verify user belongs to tenant
if request.user.tenant_id != tenant_id:
raise Forbidden("Cross-tenant access denied")
# All queries scoped to tenant
projects = Project.objects.filter(tenant_id=tenant_id)
# ...
Performance Optimization
Caching Strategy
CACHE_TTL = {
'portfolio_summary': 60, # 1 min
'kanban_board': 30, # 30 sec
'activity_feed': 60, # 1 min
'work_distribution': 300, # 5 min
}
Materialized Views
-- Pre-computed project progress
CREATE MATERIALIZED VIEW project_progress AS
SELECT
p.id AS project_id,
p.name,
COUNT(t.id) AS total_tasks,
COUNT(t.id) FILTER (WHERE t.checked = TRUE) AS completed_tasks,
ROUND((COUNT(t.id) FILTER (WHERE t.checked = TRUE)::decimal / COUNT(t.id)) * 100, 1) AS progress_pct
FROM projects p
LEFT JOIN tasks t ON t.project_id = p.id
GROUP BY p.id, p.name;
-- Refresh every 5 minutes
CREATE INDEX idx_project_progress_refresh ON project_progress (project_id);
Security Considerations
- Tenant Isolation: NEVER expose cross-tenant data
- Role Permissions: Always check user.role before mutations
- WebSocket Auth: Require JWT token in WebSocket connection
- SQL Injection: Use parameterized queries (NEVER string concatenation)
- XSS Prevention: Sanitize all user-provided content before display
Document Version: 2.0 Last Updated: November 27, 2025 Maintained By: Dashboard Team Related Docs: sdd-activity-dashboard.md, tdd-activity-dashboard.md, ad-rs-activity-dashboard.md