Multi-Project Dashboard Design
Coditect Activity Dashboard - Complete Design Package
Version: 1.0
Date: November 27, 2025
Status: Final Design
Classification: Internal Architecture Document
Table of Contents
- Executive Summary
- Design Philosophy
- Software Design Document
- Technical Design Document
- Architecture Decision Records
- UI Component Specifications
- Implementation Guide
Part 1: Executive Summary
Vision Statementβ
The Coditect Activity Dashboard transforms how development teams track progress by showing what has been built, not how the machinery works. Users see features, deliverables, and milestonesβnot conversations, messages, and sessions.
Core Insightβ
"The gold isn't in how is it doing it... the real stuff is features, deliverables, targets reached." β Stakeholder Analysis, November 2025
The Navigation Metaphorβ
The dashboard functions like a GPS navigation system, not an engine diagnostics panel:
| GPS Concept | Dashboard Equivalent |
|---|---|
| Where Am I? | Current task progress |
| Where Going? | Project milestones |
| What Route? | Task β Commit β Done |
| Obstacles? | Blocked tasks only |
Key Design Principlesβ
- Task-Centric Architecture - All data flows toward task progress
- Checkbox as Truth -
TASK.checkedis the source of completion status - Exception-Based Display - Show anomalies, hide uniform data
- Three-Level Hierarchy - Primary (non-scrolling) β Drill-down β Deep inspection
- Real-Time Updates - WebSocket-based live synchronization
Primary Data Sourcesβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DATA SOURCES β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β LLM Sessions β β Git Commits β β Task Lists β β
β β Conversationsβ β Code Changes β β β Checkboxes β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β β β
β βββββββββββββββββββββΌββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββ β
β β LINKING SERVICE β β
β β SessionβTask β β
β β CommitβTask β β
β ββββββββββ¬ββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββ β
β β DASHBOARD β β
β β Task-Centric Viewβ β
β ββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Success Criteria: The 5-Second Testβ
Users can answer without scrolling in < 5 seconds:
- 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 (5 items)
- Am I on track? β Progress bars + task counts
Part 2: Design Philosophy
2.1 GPS Navigation vs Engine Diagnosticsβ
What We're Removingβ
| Engine Metric | Why Remove |
|---|---|
| Message counts | No actionable signal |
| Session duration | Shows process, not progress |
| Token usage | Engine internals |
| Word counts | Machinery metric |
| Uniform QA scores | "40, 40, 40, 40" = no information |
What We're Keepingβ
| Navigation Element | Why Keep |
|---|---|
| Task checkboxes | Source of truth |
| Project progress | High-level position |
| Blocked tasks | Obstacles on route |
| Linked commits | Evidence of progress |
| Activity highlights | Journey milestones |
2.2 Information Hierarchyβ
LEVEL 1: PRIMARY VIEW (Non-scrolling, ~800px viewport)
βββ Portfolio summary bar (all projects)
βββ Task Kanban (selected project)
βββ 5 activity highlights
βββ Blocked tasks panel
βββ Work distribution chart
LEVEL 2: DRILL-DOWN (On-demand)
βββ Full task list with details
βββ Commit timeline
βββ Session summaries
βββ Progress burndown
LEVEL 3: DEEP INSPECTION (Hidden)
βββ Session message history
βββ Commit diffs
βββ Task change history
βββ Raw activity logs
2.3 Exception-Based Display Rulesβ
Principle: Only show what deviates from expected baseline.
| Metric | Baseline | Display Rule |
|---|---|---|
| QA Score | 40 (passing) | Show only if < 40 |
| Task Status | Normal flow | Show only if blocked |
| Build Status | Success | Show only if failed |
| Version | Current | Show only if outdated |
Part 3: Software Design Document
3.1 System Architectureβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SYSTEM ARCHITECTURE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β FRONTEND LAYER β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β Dashboard β β Kanban β β Activity β β Blocker β β β
β β β Page β β Board β β Feed β β Panel β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β API LAYER β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β REST: /dashboard | /projects | /tasks | /commits | /sessions ββ β
β β β WebSocket: /ws/dashboard (real-time updates) ββ β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β SERVICE LAYER β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β β Dashboard β β Linking β β Progress β β β
β β β Service β β Service β β Calculator β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β β Activity β β Project β β Task β β β
β β β Aggregator β β Service β β Service β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β DATA LAYER β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β β FoundationDB β β Redis Cache β β Git Provider β β β
β β β (Primary) β β (Dashboard) β β (Webhooks) β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3.2 Data Modelβ
Entity Relationship Diagramβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DATA MODEL β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β PROJECT ββββββββββββββ¬ββββββββββββββββββ¬ββββββββββββββββββββββ β
β β’ id β β β β
β β’ name β β β β
β β’ status βΌ βΌ βΌ β
β GIT_REPO PROJECT_PLAN LLM_SESSION β
β β’ id β’ id β’ id β
β β’ url β’ name β’ started_at β
β β’ branch β’ target_date β’ summary β
β β β β β
β βΌ βΌ β β
β GIT_COMMIT TASK_LIST β β
β β’ sha β’ id β β
β β’ message β’ name β β
β β’ author β’ category β β
β β’ additions β β β
β β’ deletions βΌ β β
β β TASK ββββββββββββββββββββββ β
β β β’ id (linked via β
β β β’ title session_links) β
β β β’ checked β β
β β β’ status β
β β β’ complexity β
β β β² β
β βββββββββββββββββββ β
β (linked via commit_links) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Database Schemaβ
-- Core Entities
CREATE TABLE projects (
id UUID PRIMARY KEY,
name VARCHAR(255) NOT NULL,
status VARCHAR(50) DEFAULT 'active',
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE project_plans (
id UUID PRIMARY KEY,
project_id UUID REFERENCES projects(id),
name VARCHAR(255) NOT NULL,
target_date DATE
);
CREATE TABLE task_lists (
id UUID PRIMARY KEY,
plan_id UUID REFERENCES project_plans(id),
name VARCHAR(255) NOT NULL,
category VARCHAR(100)
);
CREATE TABLE tasks (
id UUID PRIMARY KEY,
list_id UUID REFERENCES task_lists(id),
title VARCHAR(500) NOT NULL,
checked BOOLEAN DEFAULT FALSE, -- SOURCE OF TRUTH
status VARCHAR(50) DEFAULT 'pending',
complexity VARCHAR(10),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE llm_sessions (
id UUID PRIMARY KEY,
project_id UUID REFERENCES projects(id),
started_at TIMESTAMP DEFAULT NOW(),
ended_at TIMESTAMP,
message_count INTEGER DEFAULT 0,
summary TEXT
);
CREATE TABLE git_commits (
sha VARCHAR(40) PRIMARY KEY,
repo_id UUID REFERENCES git_repos(id),
message TEXT NOT NULL,
author VARCHAR(255),
timestamp TIMESTAMP,
additions INTEGER,
deletions INTEGER
);
-- Linking Tables
CREATE TABLE task_commit_links (
task_id UUID REFERENCES tasks(id),
commit_sha VARCHAR(40) REFERENCES git_commits(sha),
confidence DECIMAL(3,2),
link_type VARCHAR(20),
PRIMARY KEY (task_id, commit_sha)
);
CREATE TABLE task_session_links (
task_id UUID REFERENCES tasks(id),
session_id UUID REFERENCES llm_sessions(id),
confidence DECIMAL(3,2),
link_type VARCHAR(20),
PRIMARY KEY (task_id, session_id)
);
3.3 API Specificationsβ
REST Endpointsβ
GET /api/v1/dashboard
β DashboardResponse (portfolio + selected project + activity + blockers)
GET /api/v1/dashboard/portfolio
β ProjectSummary[] (all projects with progress)
GET /api/v1/dashboard/activity?limit=5
β ActivityHighlight[] (prioritized recent events)
GET /api/v1/projects/{id}/kanban
β KanbanBoard (tasks grouped by status)
PATCH /api/v1/tasks/{id}
β Task (update checked/status)
WebSocket Eventsβ
Server β Client:
β’ task.updated { task_id, changes }
β’ task.completed { task_id, project_id }
β’ task.blocked { task_id, reason }
β’ progress.changed { project_id, new_progress }
β’ commit.new { commit, linked_tasks }
Client β Server:
β’ subscribe { project_ids: string[] }
β’ unsubscribe { project_ids: string[] }
Part 4: Technical Design Document
4.1 Task Linking Algorithmsβ
Commit-to-Task Linkingβ
class CommitTaskLinker:
"""Links git commits to tasks using multiple strategies"""
STRATEGIES = [
('explicit', 1.0), # #TASK-123 in message
('title', 0.5-0.9), # Title similarity > 0.7
('files', 0.3-0.6), # File path overlap
]
async def link_commit(self, commit, project_id) -> List[LinkResult]:
# 1. Check explicit references (highest priority)
explicit = self.find_explicit_refs(commit.message)
if explicit:
return explicit # confidence = 1.0
# 2. Title similarity matching
title_matches = self.match_by_title(
commit.message,
project_tasks,
threshold=0.7
)
# 3. File overlap analysis
file_matches = self.match_by_files(
commit.files_changed,
project_task_files
)
return self.merge_results(title_matches, file_matches)
Session-to-Task Linkingβ
class SessionTaskLinker:
"""Links LLM sessions to tasks using NLP analysis"""
KEYWORD_THRESHOLD = 3 # Minimum keyword matches
async def link_session(self, session, project_id) -> List[LinkResult]:
# Extract keywords from session
keywords = self.extract_keywords(session.summary)
entities = self.extract_entities(session.messages)
# Match against task titles/descriptions
for task in project_tasks:
score = self.calculate_match_score(
keywords, entities, task
)
if score >= self.KEYWORD_THRESHOLD:
results.append(LinkResult(
task_id=task.id,
confidence=min(0.9, score / 10),
link_type='inferred'
))
return results[:5] # Top 5 matches
4.2 Progress Calculationβ
class ProgressCalculator:
"""
Progress = checked_tasks / total_tasks Γ 100
The TASK.checked boolean is the source of truth.
"""
async def calculate_project_progress(self, project_id) -> ProgressMetrics:
tasks = await self.task_repo.get_by_project(project_id)
total = len(tasks)
completed = sum(1 for t in tasks if t.checked)
return ProgressMetrics(
progress_pct = (completed / total * 100) if total > 0 else 0,
tasks_completed = completed,
tasks_total = total,
tasks_by_status = self.count_by_status(tasks)
)
4.3 Activity Feed Prioritizationβ
PRIORITY_WEIGHTS = {
'task_completed': 100, # Highest: deliverable achieved
'task_blocked': 90, # High: needs attention
'commit_merged': 60, # Medium-high: code shipped
'commit_pushed': 50, # Medium: work evidence
'status_change': 40, # Medium-low: workflow update
'session_ended': 30, # Low: just process
}
def get_activity_feed(limit=5) -> List[ActivityHighlight]:
activities = collect_all_activities(last_7_days)
# Sort by (priority DESC, timestamp DESC)
activities.sort(key=lambda x: (
PRIORITY_WEIGHTS[x.type],
x.timestamp
), reverse=True)
# Always include blockers
blockers = [a for a in activities if a.type == 'task_blocked']
others = [a for a in activities if a.type != 'task_blocked']
return (blockers + others)[:limit]
4.4 Real-Time Updatesβ
class DashboardWebSocketManager:
"""Manages WebSocket connections for live updates"""
async def broadcast_task_update(self, task, change_type):
await self.broadcast_to_project(
task.project_id,
f'task.{change_type}',
{'task_id': task.id, 'changes': task.to_dict()}
)
# Recalculate and broadcast progress
if change_type in ('completed', 'uncompleted'):
progress = await self.progress_calc.calculate(task.project_id)
await self.broadcast_to_project(
task.project_id,
'progress.changed',
{'progress_pct': progress.progress_pct}
)
4.5 Caching Strategyβ
| Data | TTL | Invalidation |
|---|---|---|
| Portfolio summary | 60s | On task update |
| Kanban board | 30s | On task update |
| Activity feed | 60s | On new activity |
| Work distribution | 300s | On commit/session |
Part 5: Architecture Decision Records
ADR-001: Task-Centric Dashboard Architectureβ
Status: Accepted
Context: Initial implementation showed session metrics (messages, duration). Users need deliverable-focused views.
Decision: Architect dashboard around tasks as primary entity. Sessions and commits are supporting evidence.
Consequences:
- β Answers "What has been accomplished?"
- β Aligns with existing mental models (Kanban, JIRA)
- β οΈ Requires building task-linking infrastructure
ADR-002: Checkbox as Source of Truthβ
Status: Accepted
Context: Progress can be derived from multiple signals (status, commits, time). Need single, unambiguous source.
Decision: TASK.checked boolean is authoritative for completion.
Progress = COUNT(checked=true) / COUNT(*) Γ 100
Consequences:
- β Unambiguous: done or not done
- β User has explicit control
- β Simple calculation
- β οΈ Binary view doesn't capture partial progress
ADR-003: Exception-Based Displayβ
Status: Accepted
Context: Dashboards show all metrics regardless of informational value, creating clutter.
Decision: Hide uniform/expected values. Only show anomalies.
"If it's 40, 40, 40, 40, 40 every time, don't show it."
Rules:
- QA Score 40 = hide (only show if < 40)
- Status = normal flow β hide
- Status = blocked β SHOW prominently
ADR-004: Session-to-Task Linking Strategyβ
Status: Accepted
Context: No explicit link between sessions and tasks. Need to infer relationships.
Decision: Multi-strategy linking with confidence scores:
- Explicit references (confidence: 1.0) - Task ID in session
- Title similarity (confidence: 0.5-0.9) - NLP matching
- Keyword extraction (confidence: 0.3-0.8) - Term overlap
Links with confidence < 0.3 are discarded.
ADR-005: Real-Time Update Architectureβ
Status: Accepted
Context: Dashboard shows time-sensitive data that changes frequently.
Decision: WebSocket with pub/sub model.
- Clients subscribe to project IDs
- Server broadcasts events on changes
- Automatic reconnection with exponential backoff
- Fallback to polling if WebSocket unavailable
ADR-006: Three-Level Information Hierarchyβ
Status: Accepted
Context: Users have different needs: quick status check vs deep investigation.
Decision: Progressive disclosure with three levels:
- Level 1: Primary view (non-scrolling, 800px)
- Level 2: Drill-down (on-demand)
- Level 3: Deep inspection (hidden)
Constraint: Level 1 must fit without scrolling.
ADR-007: Activity Feed Prioritizationβ
Status: Accepted
Context: Feed limited to 5 items. Need principled selection.
Decision: Weighted prioritization:
task_completed: 100 (highest)
task_blocked: 90
commit: 50
session: 30 (lowest)
Sort by (priority DESC, timestamp DESC), take top 5. Always include blockers even if older.
ADR-008: Multi-Project Portfolio Architectureβ
Status: Accepted
Context: Users work on multiple projects simultaneously.
Decision: Portfolio model with project-level isolation:
Portfolio (User level)
βββ Project A
β βββ Git Repo(s)
β βββ Project Plan β Task Lists β Tasks
β βββ LLM Sessions
βββ Project B
βββ Project N
Dashboard modes:
- Portfolio mode: All projects visible
- Project mode: Single project focus
Part 6: UI Component Specifications
6.1 Dashboard Layoutβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CODITECT [All Projects βΌ] [β Settings] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββ PROJECT SUMMARY BAR βββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Auth System βββββββββββββββββββββ 58% β 7/12 tasks β 3 commits β β
β β Payment Gateway ββββββββββββββββββββ 40% β 4/10 tasks β 1 commit β β
β β User Dashboard ββββββββββββββββββββ 70% β 14/20 tasks β 5 commits β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββ TASK JOURNEY βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β PENDING (2) β IN PROGRESS (2) β REVIEW (0) β DONE (3) ββ
β β ββββββββββββ β ββββββββββββββββ β βββββββββββ β βββββββββββββββββ ββ
β β ββ Rate β β ββ Refresh β β β β β ββ JWT Tokens β ββ
β β β Limitingβ β β Token Logicβ β β Empty β β ββ Auth Schema β ββ
β β ββββββββββββ β β 60% ββββββ β β β β β ββ Login Form β ββ
β β ββββββββββββ β ββββββββββββββββ β βββββββββββ β βββββββββββββββββ ββ
β β ββ Error β β ββββββββββββββββ β β ββ
β β β Handling β β ββ MFA Setup β β β ββ
β β ββββββββββββ β β β οΈ BLOCKED β β β ββ
β β β ββββββββββββββββ β β ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β ββ RECENT ACTIVITY βββββββββββββββ ββ ATTENTION REQUIRED βββββββββββββββ β
β β β β β β
β β β JWT tokens complete 2h β β β οΈ MFA Setup β β
β β 3 commits, 2 sessions β β Blocked: Awaiting API spec β β
β β β β Project: Auth System β β
β β β abc123: Add refresh 3h β β Blocked for: 3 days β β
β β +45/-12 lines β β [View Task] [Mark Resolved] β β
β β β β β β
β β β Login form merged 5h β β βββββββββββββββββββββββββββββ β β
β β PR #42 approved β β No other blockers β β
β β β β β β
β β π¬ Rate limiting design 6h β β β β
β β β β β β
β β β οΈ MFA Setup blocked 8h β β β β
β β β β β β
β ββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββ β
β β
β ββ WORK DISTRIBUTION (This Week) βββββββββββββββββββββββββββββββββββββββ β
β β Auth System ββββββββββββββββββββββββββββββββββββββββββββββ 45% β β
β β Payment Gateway ββββββββββββββββββββββββββββββββββββββββββββββ 25% β β
β β User Dashboard ββββββββββββββββββββββββββββββββββββββββββββββ 20% β β
β β Documentation ββββββββββββββββββββββββββββββββββββββββββββββ 10% β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
6.2 Component Specificationsβ
ProjectSummaryBarβ
interface ProjectSummaryBarProps {
projects: ProjectSummary[];
selectedProjectId: string | null;
onProjectSelect: (projectId: string) => void;
}
interface ProjectSummary {
id: string;
name: string;
progress_pct: number;
tasks_completed: number;
tasks_total: number;
commits_count: number;
has_blockers: boolean; // Red dot indicator
}
Styling:
- Row height: 48px
- Progress bar: 200px wide, green fill (#22c55e)
- Selected: Blue left border (3px, #3b82f6)
- Blocker indicator: Red dot if
has_blockers=true
KanbanBoardβ
interface KanbanBoardProps {
kanban: KanbanBoard;
onTaskClick: (taskId: string) => void;
onTaskMove?: (taskId: string, newStatus: string) => void;
}
interface KanbanBoard {
columns: KanbanColumn[];
}
interface KanbanColumn {
status: 'pending' | 'in_progress' | 'review' | 'done';
label: string;
tasks: TaskCard[];
count: number;
}
Column Colors:
- Pending: Gray (#6b7280)
- In Progress: Blue (#3b82f6)
- Review: Purple (#8b5cf6)
- Done: Green (#22c55e)
Blocked Tasks: Orange left border (#f59e0b) within In Progress column
TaskCardβ
interface TaskCardProps {
task: TaskCard;
onToggle: (taskId: string, checked: boolean) => void;
onClick: (taskId: string) => void;
}
interface TaskCard {
id: string;
title: string;
checked: boolean;
status: TaskStatus;
complexity?: 'S' | 'M' | 'L' | 'XL';
progress?: number; // 0-100, only for in_progress
linked_commits_count: number;
linked_sessions_count: number;
blocked_reason?: string;
}
States:
- Default: White background
- Hover: Light blue (#f0f9ff)
- Blocked: Orange border + "BLOCKED" badge
- Completed: Muted colors, strikethrough title
ActivityFeedβ
interface ActivityFeedProps {
activities: ActivityHighlight[];
onActivityClick: (id: string, type: string) => void;
maxItems?: number; // Default: 5
}
interface ActivityHighlight {
id: string;
type: 'task_completed' | 'commit' | 'session' | 'blocked';
title: string;
subtitle?: string;
project_id: string;
project_name: string;
task_id?: string;
timestamp: string;
icon: 'check' | 'git' | 'chat' | 'alert';
}
Icons:
- β task_completed (green)
- β commit (purple)
- π¬ session (blue)
- β οΈ blocked (orange)
BlockerPanelβ
interface BlockerPanelProps {
blockers: BlockedTask[];
onViewTask: (taskId: string) => void;
onResolve: (taskId: string) => void;
}
interface BlockedTask {
task_id: string;
task_title: string;
project_id: string;
project_name: string;
task_list_name: string;
blocked_reason?: string;
days_blocked: number;
}
Styling:
- Background: Warm amber (#fffbeb)
- Border: Amber (#fcd34d)
- Days badge: Red if > 3 days
Empty State: "No blockers - all clear! β" with green styling
WorkDistributionChartβ
interface WorkDistributionChartProps {
distribution: WorkDistribution[];
timeRange: 'day' | 'week' | 'month';
onTimeRangeChange: (range: string) => void;
onProjectClick: (projectId: string) => void;
}
interface WorkDistribution {
project_id: string;
project_name: string;
percentage: number;
commit_count: number;
session_count: number;
tasks_completed: number;
color: string;
}
Calculation:
weighted_score = commitsΓ3 + sessionsΓ1 + tasksΓ5
percentage = project_score / total_score Γ 100
6.3 Color Paletteβ
/* Background */
--bg-primary: #f3f4f6;
--bg-card: #ffffff;
/* Status Colors */
--status-success: #22c55e;
--status-warning: #f59e0b;
--status-error: #ef4444;
--status-info: #3b82f6;
/* Kanban Columns */
--column-pending: #6b7280;
--column-progress: #3b82f6;
--column-review: #8b5cf6;
--column-done: #22c55e;
/* Text */
--text-primary: #111827;
--text-secondary: #6b7280;
/* Borders */
--border-default: #e5e7eb;
Part 7: Implementation Guide
7.1 Priority Matrixβ
| Priority | Component | Effort | Dependencies |
|---|---|---|---|
| P0 | Multi-Project Data Model | M | None |
| P0 | Task Kanban Board | M | Data Model |
| P0 | Checkbox-Based Progress | S | Data Model |
| P0 | Blocked Task Detection | S | Data Model |
| P1 | Project Summary Bar | M | Progress Calc |
| P1 | Activity Feed (5 items) | M | All sources |
| P1 | SessionβTask Linking | L | NLP setup |
| P1 | CommitβTask Linking | M | Git webhooks |
| P2 | Work Distribution | M | Linking |
| P2 | Real-Time Updates | M | WebSocket |
| P3 | Drill-Down Views | L | All P1 |
7.2 Implementation Phasesβ
Phase 1: Foundation (2 weeks)β
- Multi-project data model
- Task CRUD with checkbox
- Basic Kanban view
- Blocked task panel
Phase 2: Linking (2 weeks)β
- Commit-to-task linking
- Session-to-task linking
- Confidence scoring
- Link management UI
Phase 3: Dashboard (2 weeks)β
- Project summary bar
- Activity feed
- Work distribution
- Progress calculations
Phase 4: Real-Time (1 week)β
- WebSocket infrastructure
- Event broadcasting
- Optimistic updates
- Reconnection handling
Phase 5: Polish (1 week)β
- Caching optimization
- Performance tuning
- Responsive design
- Accessibility
7.3 Testing Strategyβ
Unit Testsβ
- Progress calculation
- Linking algorithms
- Activity prioritization
Integration Testsβ
- API endpoints
- WebSocket events
- Cache invalidation
E2E Testsβ
- 5-second test scenarios
- Cross-project navigation
- Blocker workflows
Appendix A: TypeScript Interfaces
// Core Types
type TaskStatus = 'pending' | 'in_progress' | 'review' | 'blocked' | 'done';
type ActivityType = 'task_completed' | 'commit' | 'session' | 'status_change' | 'blocked';
type TimeRange = 'day' | 'week' | 'month';
// API Response
interface DashboardResponse {
portfolio_summary: ProjectSummary[];
selected_project?: {
project: Project;
kanban: KanbanBoard;
};
recent_activity: ActivityHighlight[];
blocked_tasks: BlockedTask[];
work_distribution: WorkDistribution[];
last_updated: string;
}
// WebSocket Events
interface TaskUpdateEvent {
type: 'task.updated' | 'task.completed' | 'task.blocked';
project_id: string;
task_id: string;
changes: Partial<Task>;
}
interface ProgressUpdateEvent {
type: 'progress.changed';
project_id: string;
progress_pct: number;
tasks_completed: number;
tasks_total: number;
}
Appendix B: Key Stakeholder Quotes
"The gold isn't in how is it doing it... the real stuff is features, deliverables, targets reached."
"What you want is: How do I get from A to B? What are my obstacles? And what's my route?"
"If it's 40, 40, 40, 40, 40 every time, don't show it."
"5 things that happened and a simple definition of these things."
"Sessions are segments of the journey... we need to connect them into the map."
"The thing you don't want to see [is] the neurons firing. We want to see what we're thinking about."
"A Kanban board has value because you can see features moving from left to right."
Document History
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2025-11-27 | Architecture Team | Complete design package |
This document represents the complete design specification for the Coditect Multi-Project Activity Dashboard, combining Software Design, Technical Design, Architecture Decisions, and UI Component specifications into a unified reference.