# Frontend Dashboard Design

Date: 2026-04-11
Project: `acpx-teams-mcp`
Status: Draft approved for spec review

## Goal

Build a new independent web app that provides a read-only dashboard for `acpx-teams-mcp`.

The first version is a pure observation surface for internal team collaboration. It must not provide any operation that mutates team state, sends messages, changes tasks, or manages teammate sessions.

## Why This Exists

`acpx-teams-mcp` currently exposes orchestration capability through MCP tools and local file-backed state, but it has no visual surface for quickly understanding team health, task flow, and message activity.

The dashboard should answer three questions quickly:

1. What is the overall state of the system right now?
2. Which teams or members look abnormal?
3. Where should someone drill down to understand the issue?

## Product Scope

### In Scope for V1

- Independent web app
- Read-only dashboard homepage
- Quasi-realtime polling updates
- Global summary metrics
- Workflow-centric overview sections
- Team cards for drill-down
- Read-only side drawer for team details
- Filtering, sorting, searching, and manual refresh

### Out of Scope for V1

- Sending messages or broadcasts
- Editing tasks or changing owners
- Creating or deleting teams
- Spawning, shutting down, or force-killing teammates
- Processing queue actions or approvals
- Any inbox mutation action presented as a user-facing operation
- Full historical analytics or audit reporting

## Users

Primary users are internal collaborators who need to understand current system state without using the MCP tool interface directly.

The interface should be understandable to teammates who are not deeply familiar with raw MCP tool names, while still preserving operational accuracy.

## Experience Principles

- Read-only by default and by design
- Surface anomalies before completeness
- Let users go from global to specific in one screen
- Prefer simple status language over raw backend jargon where possible
- Preserve precise backend terms where they matter for diagnosis, such as `running`, `idle`, and `no-session`

## Information Architecture

The homepage has four layers.

### 1. Top Summary Strip

Shows a compact global health snapshot:

- total teams
- active teams
- online members
- running tasks
- blocked tasks
- unread message count

This area is optimized for a three-second scan.

### 2. Workflow Overview

Three adjacent sections summarize the system by workflow instead of by team:

- member state
- task state
- message activity

Each section highlights abnormal conditions first.

### 3. Team Card Grid

A grid or stacked list of team cards provides per-team summaries:

- team name
- member count and online count
- task distribution
- most recent message timestamp
- risk markers

### 4. Read-Only Detail Drawer

Selecting a team card opens a side drawer without navigating away from the homepage.

The drawer includes:

- member status list
- task list
- recent message timeline
- risk explanation

No write controls appear in the drawer.

## Screen Structure

```text
[Header / Filter Bar]
    |
    v
[Top Summary Strip]
    |
    v
[Workflow Overview]
  [Member State] [Task State] [Message Activity]
    |
    v
[Team Card Grid]
    |
    v
[Right Detail Drawer]
```

## Data Model for the UI

The UI should assemble a frontend-friendly read model from existing MCP responses.

### Team Summary Read Model

Each team summary should include:

- `teamName`
- `memberCount`
- `onlineCount`
- `runningCount`
- `idleCount`
- `noSessionCount`
- `taskCounts`
  - `pending`
  - `inProgress`
  - `completed`
  - `blocked`
- `lastMessageAt`
- `unreadMessageCount`
- `riskFlags`

### Team Detail Read Model

Each team detail record should include:

- team metadata
- members with current status
- tasks with status, owner, dependency info
- recent messages in chronological order
- derived warnings

### Global Summary Read Model

Global metrics are computed by aggregation across all teams:

- total teams
- active teams
- total online members
- total running tasks
- total blocked tasks
- total unread messages

## Data Sources

The dashboard should be built on top of existing MCP capabilities, but the frontend should not call them directly from the browser in V1. A small web-facing backend or adapter layer should aggregate them into read-only endpoints.

### Required MCP Reads

- `read_config`
- `team_status`
- `task_list`
- `read_inbox` or an equivalent safe read aggregation path for message visibility

### Recommended Aggregation Endpoints

- `GET /api/dashboard/summary`
- `GET /api/dashboard/teams`
- `GET /api/dashboard/teams/:teamName`

This adapter layer should normalize backend tool output into stable JSON contracts for the frontend.

## Refresh Strategy

V1 uses polling rather than push-based realtime updates.

Recommended intervals:

- summary and team list: every 5 to 10 seconds
- detail drawer data: refresh on open and then every 5 seconds while visible
- manual refresh: always available

The UI should show:

- last updated timestamp
- loading state
- stale state if refresh fails

## Section Details

### Member State Section

Displays:

- counts by `running`, `idle`, `no-session`
- small anomaly list for members in `no-session` or error states

Purpose:

- make teammate health visible immediately

### Task State Section

Displays:

- counts by `pending`, `in_progress`, `completed`
- blocked task count
- short list of blocked or aging in-progress tasks

Purpose:

- show delivery flow and identify stuck work

### Message Activity Section

Displays:

- unread total
- latest message timestamp
- activity volume in a recent time window
- teams with newly active message streams

Purpose:

- show whether communication is progressing or stalled

### Team Cards

Each card should encode health at a glance:

- neutral if no risk markers
- warning if blocked tasks or unread buildup exists
- critical if one or more members are `no-session`

Cards should support:

- search by team name
- sorting by health, activity, or recency
- filtering by abnormal state

## Risk Detection Rules

Initial derived rules for V1:

- `member_no_session`: at least one member is `no-session`
- `task_blocked`: at least one task is blocked by unfinished dependencies
- `message_backlog`: unread messages exceed a threshold
- `stalled_team`: no recent message activity while tasks are still in progress

Thresholds can be simple constants in V1 and refined later.

## Error Handling

The dashboard must fail visibly but safely.

- If one team fails to load, keep the rest of the dashboard visible and mark that team as unavailable.
- If summary refresh fails, preserve the previous snapshot and show stale state.
- If detail drawer refresh fails, keep last successful data and display an inline warning.
- If a data source is unavailable, show the exact affected section rather than collapsing the full page.

## Technical Shape

### Frontend

An independent SPA is preferred for V1. Framework choice is open, but the app should support:

- polling
- derived client-side filtering and sorting
- drawer-based drill-down
- simple chart or stat components

### Backend Adapter

A lightweight HTTP adapter should sit between the browser and MCP-backed reads. Its responsibilities:

- invoke read-only MCP-backed data fetches
- aggregate and normalize responses
- avoid exposing write-capable endpoints in V1
- shield the frontend from tool-specific shapes

## Testing

Testing should cover:

- adapter aggregation logic
- derived risk flags
- empty-state and partial-failure rendering
- polling refresh behavior
- detail drawer rendering for healthy and unhealthy teams

V1 does not require end-to-end mutation testing because the product is read-only.

## Open Decisions Resolved

- The dashboard is read-only in V1.
- The product is an independent web app.
- The homepage uses mixed information architecture.
- Updates are polling-based, not websocket-based.
- The homepage is monitoring-first, not command-first.

## Implementation Boundary

This spec is intentionally limited to the first valuable dashboard slice:

- one homepage
- one detail drawer
- read aggregation endpoints
- no write actions

Anything beyond that should be treated as a later iteration, not folded into V1.
