Files
stack/docs/USER-GUIDE/product/web-dashboard.md
T
veronica f0d2dd9920 docs(W4): stamp kind and status front matter on 104 live documents
Applies the document contract from
docs/plans/2026-08-20_stack-docs-flatten-and-alignment.md section 3, partially:
`kind` and `status` only. `parent` is deliberately held until the flatten in
section 4 lands, so that 127 documents do not have to be re-pointed by hand
when docs/fleet/NORTH_STAR.yaml moves to docs/NORTH_STAR.yaml.

Scope, measured on origin/next at 63069149:

  127 live docs   = all *.md under docs/ minus docs/archive/ minus docs/_old_structure/
  104 stamped     here
   19 held        operator judgement (plan section 9), worklist in the same PR
    3 held        the SUPERSEDED TASKS.md stamps, which cite the moving path
    1 untouched   docs/fleet/FLEET-DOCTRINE.md, already stamped in W1

Kinds applied: 54 guide, 34 record, 9 spec, 6 tracking, 1 projection.
Every row carries a confidence and a one-line rationale in the worklist.

Two collisions with the existing state, both flagged rather than resolved:

1. docs/README.md:150-160 already documents a front-matter convention
   (title/type/audience/status/source_of_truth) with its own allowed values.
   It is applied to 4 of 127 files. Its `status` vocabulary is
   current|draft|deprecated|historical; the new contract's is active|superseded-by.
   The key collides. This commit lets the new contract win and rewrites
   `status: current` to `status: active` on those 4 files, keeping their other
   legacy keys untouched. No code reads any of them: `git grep source_of_truth`
   outside docs/ returns nothing. docs/README.md still prescribes the old
   convention and is an operator row, so it is not edited here.

2. Two of the plan's 20 operator rows are YAML files, not markdown
   (docs/fleet/examples/roster-v2.yaml, docs/openapi-tess.yaml), and the
   contract's front-matter form has no defined meaning for a .yaml document.
   That gap also applies to docs/fleet/NORTH_STAR.yaml, the source of truth
   itself. Raised in the worklist.

A third row from the plan, docs/fleet/north-star.md, no longer exists: W1
renamed it to docs/fleet/FLEET-DOCTRINE.md.

Verification: 104/104 parse with the expected kind and status in front matter;
the check was shown to reject a wrong kind before it was trusted. The diff
removes 4 lines total, all of them `status: current`.
2026-08-20 19:30:25 -05:00

278 lines
14 KiB
Markdown

---
kind: guide
status: active
title: Mosaic web dashboard
type: guide
audience: user
source_of_truth: false
---
# Mosaic Web Dashboard
This page documents the current Next.js dashboard: its routes, navigation, visible
views, and the chat persistence behavior supported by the checked-in web and gateway
implementation.
> **Current UI boundary:** Projects and tasks can be displayed in the dashboard, but
> the current dashboard does not provide **New Project** or **New Task** controls.
> Those entities can be created through authenticated gateway API clients; that API
> surface is separate from the views described here.
## Access and routes
The dashboard uses the gateway session. Dashboard routes are protected by the web
`AuthGuard`; the admin route also requires the `admin` role.
| Path | Access | Current behavior |
| --------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/` | Any | Redirects to `/chat`. A signed-out visitor is then redirected to `/login`. |
| `/login` | Signed out | Email/password sign-in, plus buttons for configured SSO providers. Successful sign-in returns to `/chat`. |
| `/register` | Signed out | Creates an account with name, email, and password, then returns to `/chat`. |
| `/auth/provider/[provider]` | SSO handoff | Looks up the requested provider and starts an OIDC sign-in when that provider is configured and supports OIDC. Unknown, disabled, or incompatible providers show an error and a link back to login. |
| `/chat` | Signed in | Conversation list and streamed assistant chat. |
| `/projects` | Signed in | Project cards and the Active Mission status section. |
| `/projects/[id]` | Signed in | Project detail view with overview, tasks, missions, and an optional read-only PRD tab. |
| `/tasks` | Signed in | Task data in Kanban or list view. |
| `/settings` | Signed in | Profile, appearance, notifications, and provider tabs. |
| `/admin` | Signed-in admin | User Management and System Health tabs. Non-admin users are redirected away from the admin page. |
Settings and admin tabs are client-side tabs; changing a tab does not change the URL.
## Dashboard navigation
The **Workspace** sidebar contains these links, in order:
1. **Chat**`/chat`
2. **Tasks**`/tasks`
3. **Projects**`/projects`
4. **Settings**`/settings`
5. **Admin**`/admin`
The active link is highlighted, including the parent link when viewing a project
such as `/projects/<id>`. The Admin link is rendered in the shared sidebar, but the
page itself is still restricted to administrators.
The top bar provides:
- a sidebar toggle (collapse/expand on desktop; open/close an overlay on mobile),
- the light/dark theme toggle,
- the signed-in user's name, and
- **Sign out**, which returns to `/login`.
The applied global theme is stored in browser local storage under `mosaic-theme`.
## Chat
### Starting and managing conversations
Open `/chat` and either select a conversation or choose **Start new conversation**
in the empty state. The conversation sidebar also has **New conversation**. Creating
one calls the gateway and gives the conversation a server-side ID before the first
message is sent.
The sidebar currently supports:
- searching conversation titles,
- selecting a conversation,
- renaming a conversation inline (Enter or leaving the field commits the new title),
- deleting a conversation after confirmation, and
- grouping conversations by project when project data is available.
Archived conversations are filtered out of the sidebar. The current dashboard does
not expose archive/restore controls.
If no conversation is selected when a message is sent, the dashboard creates one
automatically. A new conversation is titled from the first 60 characters of the
first message; an empty placeholder conversation is similarly retitled after its
first message. The active conversation is held in page state, not in the URL: the
route remains `/chat` rather than changing to `/chat/<id>`. After a refresh, select
the stored conversation again from the sidebar.
### Sending and streaming
The chat composer provides:
- a model selector populated from available gateway providers and models,
- a multiline message field,
- character and approximate token counts, and
- a **Send** button.
Use **Cmd/Ctrl+Enter** to send. The composer is disabled while a response is
streaming. The interface displays a **Stop** control during streaming, but the
current `ChatPage` does not pass a stop handler, so cancellation is not a reliable
current dashboard action.
Assistant and user messages render Markdown. Assistant messages can show model and
token metadata when it is present in the returned message, and rendered user/assistant
messages have a copy control.
### What is persisted
Assistant replies are not page-only or memory-only. The current flow is:
1. The browser creates or selects a conversation and optimistically displays the
user's message.
2. The browser submits the user message to the gateway conversation-message API and
sends the turn over the authenticated `/chat` WebSocket namespace.
3. The gateway streams the assistant response to the page. At `agent_end`, it saves
non-empty assistant text to the conversation with model, provider, tool-call, and
token-usage metadata when available.
4. Selecting the conversation later loads `/api/conversations/<id>/messages`, so
stored user and assistant messages are shown again. When the gateway has to create
or resume the agent session for that conversation, it also loads stored conversation
history as context.
The live page appends the completed response as soon as the stream ends; the gateway
persistence write is asynchronous. Therefore a persistence error can leave a reply
visible in the current page while it is unavailable after a later reload. The gateway
redacts sensitive content before emitting and storing assistant text.
## Projects and missions
### Project list: `/projects`
The project page loads the signed-in user's projects and shows either:
- project cards with name, status, description, and creation date, or
- **No projects yet** with the message that projects appear when created through the
gateway API.
The page also shows **Active Mission**. It reports the mission ID, phase, task
completion count, and status when coordination data is available; otherwise it
shows **No active mission detected**.
There is no New Project button or project form on this page. The gateway has
project CRUD endpoints, but this dashboard page currently reads project data only.
### Project detail: `/projects/<id>`
A project detail page shows its name, status, description, created/updated dates,
and task summary counts for total, done, in progress, and blocked tasks. Its tabs
are:
- **Overview** — up to five recently updated tasks, a mission summary, and non-empty
project metadata.
- **Tasks (`n`)** — task status filters and clickable task rows.
- **Missions (`n`)** — a status-ordered mission timeline.
- **PRD** — present only when project metadata contains non-empty `prd` or
`prdContent` text; the content is displayed read-only.
Selecting a task from the project detail Tasks tab opens a detail dialog with its
status, priority, description, assignee, due date, timestamps, tags, pull-request
links, and notes when those fields exist. The dialog can be closed with its close
button, the backdrop, or Escape. The dashboard does not provide project or task
edit controls in this view.
## Tasks
Open `/tasks` to load the tasks visible to the signed-in user. The default view is
**Kanban**; a toggle switches to **List**.
- Kanban columns are **Not Started**, **In Progress**, **Blocked**, and **Done**.
- Kanban cards show title, priority, optional description, status, and due date.
- List view shows title, status, priority, and due date.
- The supported task status set also includes `cancelled`; it is not a Kanban
column, but a returned cancelled task can appear in List view.
The top-level Tasks page has no New Task button, form, or working task edit dialog.
Clicking a task in that page does not open the project-detail dialog. The gateway
supports authenticated task CRUD separately, while this dashboard page currently
reads and presents task data.
## Settings
Open `/settings`. The page has four tabs and opens on **Profile**.
### Profile
- **Display Name** can be edited.
- **Email** is displayed but disabled; the page says it cannot be changed there.
- **Avatar URL** can be edited.
- **Save changes** sends the profile update through BetterAuth and reports saving,
saved, or an error state.
### Appearance
The tab presents **System**, **Light**, and **Dark** theme choices, a **Collapse
sidebar by default** switch, and a **Default Model** text field. **Save changes**
saves these as user preferences.
Current implementation limits are worth noting: the shared sidebar provider starts
expanded and does not read `ui.sidebar_collapsed` on page load; the global applied
theme is controlled by the top-bar theme toggle; and the chat page initially selects
the first available provider model rather than reading `ui.default_model` itself.
Do not treat these preference fields as proof that those defaults are applied across
all dashboard sessions.
### Notifications
The tab presents and saves three email preferences:
- **Agent task completed** — initially off,
- **Mentions** — initially on, and
- **Weekly digest** — initially off.
### Providers
The Providers tab contains SSO discovery and LLM provider discovery/testing areas:
- **SSO Providers** shows configured providers and their protocols, callback path,
team-sync claim, SAML fallback, and warnings when supplied by the gateway. It does
not configure SSO from the dashboard.
- **LLM Providers** shows configured providers as Active or Inactive. A provider can
be tested for reachability; the result may include latency, an error, and the
number of discovered models. Expanding a provider shows model capabilities,
context size, cost, and the default-model marker.
When no LLM providers are configured, the page displays setup guidance mentioning
`OLLAMA_BASE_URL` and `MOSAIC_CUSTOM_PROVIDERS`. Provider credentials and provider
configuration are not editable in this dashboard tab.
## Admin panel
The `/admin` page is wrapped in an admin-role guard. It opens on **User Management**
and provides **System Health** as the second tab.
### User Management
The page loads the user list and provides:
- a user count,
- **+ New User**, with name, email, password, and `member`/`admin` role fields,
- role promotion/demotion,
- ban/unban,
- deletion after confirmation, and
- a retry action when loading fails.
The table shows name/email, role, active or banned status, creation date, and
available actions.
### System Health
The health tab loads the gateway's overall `ok` or `degraded` status and provides a
**Refresh** action. Its cards cover:
- PostgreSQL database status and latency/error,
- Valkey cache status and latency/error,
- active agent-session count, and
- configured LLM providers and model counts.
## Evidence used for this page
The behavior above was checked against the current implementation and focused tests,
not copied forward as-is from the historical mixed guide. The main evidence files
are:
- `apps/web/src/app/(dashboard)/` route pages and `apps/web/src/app/page.tsx`,
- `apps/web/src/components/layout/`, `apps/web/src/components/chat/`,
`apps/web/src/components/projects/`, and `apps/web/src/components/tasks/`,
- `apps/web/e2e/navigation.spec.ts`, `chat.spec.ts`, `projects.spec.ts`,
`settings.spec.ts`, and `admin.spec.ts`,
- `apps/gateway/src/chat/chat.gateway.ts` and
`apps/gateway/src/__tests__/conversation-persistence.test.ts`,
- `apps/gateway/src/chat/chat.gateway-redaction.spec.ts`, and
- the authenticated gateway controllers under `apps/gateway/src/conversations/`,
`projects/`, `tasks/`, and `admin/`.
Related: [User Guide index](../README.md) and [SSO provider runbook](../../ADMIN-GUIDE/security/sso-providers.md).