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.