---
path: /status
surface: tenant-admin
domain: operations
auth: signed-in + tenant:admin (getTenantServerSession)
source: apps/oshun/tenant-admin/src/app/status/page.tsx
status: drafted
last_walked: '—'
---

# Status and maintenance

## Purpose

Read-only tenant-visible status surface: aggregates component health, active
incidents, scheduled maintenance, SLA-breach signal, escalation plan, active
banners, and postmortem visibility into one panel. Backs the `status` workspace
(`governance` group) in `libs/oshun/navigation/src/tenant-ia.ts`.

## Entry points

- Shell sidebar (`TenantSidebar`) — **"Status"** (`shortLabel`) under the
  **Governance** group, link to `/status` (`data-workspace-id="status"`)
- Workspace grid on `/` (home) — list item `data-workspace-id="status"`
- Direct URL `/status` (bookmarkable; middleware-gated)

## Layout regions

Inside `TenantShell`:

- **Header**: `TenantHeader` shows `tenant · <tenantId>` › **"Status and
  maintenance"**
- **Main**:
  `<section data-testid="tenant-status-panel" data-tenant-id={tenantId}>`
  - `<h1>Status and maintenance</h1>` + subtitle paragraph
  - `.summaryGrid` — four tiles: **Overall** (`view.overall`), **Active
    incidents** (`view.activeIncidents.length`), **SLA breach** ("Yes"/"No"),
    **Escalations** (`escalation?.steps.length ?? 0`)
  - `.table` — two evidence rows: **Banner** (message + active count,
    `badgeWarn`) and **Postmortem** (visibility badge: `badgeGood` "visible" /
    `badgeBad` "hidden")

## States

- [ ] **Loading** — N/A; server component computes the status view in one pass
- [ ] **Empty** — N/A; the fixture always includes one incident, one banner, one
      postmortem
- [ ] **Populated (short)** — both evidence rows render; summary tiles reflect
      `buildStatusPageView`, `evaluateSlo`, `planEscalation`
- [ ] **Populated (long)** — N/A; fixture is fixed-size
- [ ] **Error (recoverable)** — N/A; no runtime query
- [ ] **Error (unrecoverable)** — no session →
      `redirect('/unauthorized?reason=missing-session&returnTo=/status')`
- [ ] **Offline** — N/A for data (SSR-rendered)
- [ ] **Gated** — `getTenantServerSession()` null → redirect to `/unauthorized`;
      sidebar **Locked** when `canEnterTenantWorkspace` is false
- [ ] **Standalone PWA** — verify; no manifest/SW confirmed in source

## Interactions

The `<main>` content is a static report — **no buttons, inputs, banner-dismiss
control, or incident drill-in**. All interactivity is shell chrome:

- [ ] **Skip to main content** (link, `TenantShell`) → anchors `#tenant-main`
- [ ] **Sidebar workspace links** (links, `TenantSidebar`) → navigate; current
      `aria-current="page"`; **Locked** when gated
- [ ] **Evidence rows** — non-interactive; banner message / postmortem
      visibility shown as text + badges. Note: the banner fixture is
      `dismissible: true` but no dismiss control is rendered on this page

## Data & contracts

- **Reads**: no BFF/network read. The page composes pure functions from
  `@oshun/tenant-console` on in-page fixtures:
  - `buildStatusPageView({ components: ComponentHealth[], incidents, maintenance, nowUnixSeconds })`
    → `view.overall`, `view.activeIncidents`
  - `evaluateSlo({ target, availabilitySamples, latencySamples, minSamplesForVerdict, nowUnixSeconds })`
    → `slo.breached`
  - `planEscalation({ breachId, tenantId, evaluation: slo, contacts, tierDelaysSeconds, nowUnixSeconds })`
    → `escalation.steps`
  - `activeBannersFor({ banners, viewerTenantId, viewerRole, viewerLocale, fallbackLocale, nowUnixSeconds, dismissedBannerIds })`
    → `banners`
  - `postmortemVisibleTo({ postmortem, viewer })` → boolean
  - `viewerRole` hardcoded `'tenant-admin'`; `NOW = Date.UTC(2026, 4, 11, 15)`
    (seconds)
- **Writes**: _None._
- **Realtime**: _None._
- **Caching**: SSR (server component); deterministic per `tenantId`
- **Auth/role check**: `getTenantServerSession()` in page; middleware gate

Contract: `ComponentHealth` from `@oshun/tenant-console`
(`libs/oshun/tenant-console`); incidents/maintenance/SLO/banner/postmortem
shapes are inferred from the function signatures.

## Cross-references

- Workspace definition: `libs/oshun/navigation/src/tenant-ia.ts` (`status` —
  group `governance`, `requiredScopes: ['tenant:admin:*']`,
  `iconToken: 'activity'`)
- Shell: `TenantShell.tsx`, `TenantSidebar.tsx`, `TenantHeader.tsx`
- Sibling routes: [policy.md](policy.md), [roles.md](roles.md),
  [integrations.md](integrations.md), [members.md](members.md),
  [notifications.md](notifications.md)
- Conventions:
  [../WALKTHROUGH/00-conventions.md](../WALKTHROUGH/00-conventions.md)

## Open questions / known gaps

- [ ] No live status BFF route is wired — page renders a static
      component/incident/banner/postmortem fixture.
- [ ] Banner fixture is `dismissible: true` but no dismiss UI is rendered;
      `dismissedBannerIds` is always an empty `Set`. Verify whether dismissal is
      planned client-side.
- [ ] `viewerRole` is hardcoded `'tenant-admin'` rather than derived from the
      session scopes; confirm intended role-aware banner/postmortem audience.
