Skip to main content

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

  1. Executive Summary
  2. Design Philosophy
  3. Software Design Document
  4. Technical Design Document
  5. Architecture Decision Records
  6. UI Component Specifications
  7. 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 ConceptDashboard Equivalent
Where Am I?Current task progress
Where Going?Project milestones
What Route?Task β†’ Commit β†’ Done
Obstacles?Blocked tasks only

Key Design Principles​

  1. Task-Centric Architecture - All data flows toward task progress
  2. Checkbox as Truth - TASK.checked is the source of completion status
  3. Exception-Based Display - Show anomalies, hide uniform data
  4. Three-Level Hierarchy - Primary (non-scrolling) β†’ Drill-down β†’ Deep inspection
  5. 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:

  1. Which project needs attention? β†’ Project Summary Bar
  2. What tasks are in progress? β†’ Kanban Board
  3. What is blocking progress? β†’ Blocker Panel
  4. What completed recently? β†’ Activity Feed (5 items)
  5. Am I on track? β†’ Progress bars + task counts

Part 2: Design Philosophy

2.1 GPS Navigation vs Engine Diagnostics​

What We're Removing​

Engine MetricWhy Remove
Message countsNo actionable signal
Session durationShows process, not progress
Token usageEngine internals
Word countsMachinery metric
Uniform QA scores"40, 40, 40, 40" = no information

What We're Keeping​

Navigation ElementWhy Keep
Task checkboxesSource of truth
Project progressHigh-level position
Blocked tasksObstacles on route
Linked commitsEvidence of progress
Activity highlightsJourney 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.

MetricBaselineDisplay Rule
QA Score40 (passing)Show only if < 40
Task StatusNormal flowShow only if blocked
Build StatusSuccessShow only if failed
VersionCurrentShow 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​

DataTTLInvalidation
Portfolio summary60sOn task update
Kanban board30sOn task update
Activity feed60sOn new activity
Work distribution300sOn 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:

  1. Explicit references (confidence: 1.0) - Task ID in session
  2. Title similarity (confidence: 0.5-0.9) - NLP matching
  3. 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:

  1. Portfolio mode: All projects visible
  2. 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​

PriorityComponentEffortDependencies
P0Multi-Project Data ModelMNone
P0Task Kanban BoardMData Model
P0Checkbox-Based ProgressSData Model
P0Blocked Task DetectionSData Model
P1Project Summary BarMProgress Calc
P1Activity Feed (5 items)MAll sources
P1Session→Task LinkingLNLP setup
P1Commit→Task LinkingMGit webhooks
P2Work DistributionMLinking
P2Real-Time UpdatesMWebSocket
P3Drill-Down ViewsLAll 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

VersionDateAuthorChanges
1.02025-11-27Architecture TeamComplete 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.