---
path: /help
surface: tenant-admin
domain: configuration
auth: signed-in (tenant) + scope:tenant:admin:{tenantId} (or tenant:admin:*)
source: apps/oshun/tenant-admin/src/app/help/page.tsx
status: drafted
last_walked: '—'
---

# Help center

## Purpose

Resolves contextual help for the tenant admin — knowledge-base search,
in-product tooltips, changelog delivery decisions, and
feedback/editorial-backlog routing — filtered by audience, role, domain,
surface, and locale. It is the `help` workspace (`group: configuration`) in
`@oshun/navigation`.

## Entry points

- Shell sidebar **Configuration › Help** item (`TenantSidebar`,
  `shortLabel: 'Help'`, path `/help`).
- Direct URL `/help` (bookmarkable; scope-gated).

## Layout regions

Wrapped in `<TenantShell session currentWorkspaceId="help">`:

- **Sidebar / Header**: standard chrome (header crumb "Help center").
- **Main** (`<section data-testid="tenant-help-panel" data-tenant-id={...}>`):
  - `<h1>Help center</h1>` + subtitle on contextual resolution by audience /
    role / domain / surface / locale.
  - `styles.summaryGrid` of three tiles: **Search results**
    (`searchResults.length`), **Tooltips** (`contextual.tooltips.length`),
    **Changelog** (`Send`/`Skip` from `changelogDelivery`).
  - `styles.list` — one `<li>` per search result (`<strong>{title}</strong>` +
    `summary`) plus one `<li>` per feedback item
    (`<strong>Editorial backlog</strong>` + joined `missingSubjectCounts` keys).

## States

- [ ] **Loading** — N/A; synchronous server render from `searchHelp`,
      `resolveInProductHelp`, `aggregateFeedback`, `shouldDeliverChangelog` over
      one hard-coded `HelpArticle` + seed inputs (no fetch).
- [ ] **Empty** — the article matches the seeded query (`term: 'seats'`, surface
      `/members`, domain `metis`), so `searchResults` has ≥ 1 item; a
      non-matching query would yield an empty list (no `<li>` rendered, tile
      reads `0`).
- [ ] **Populated (short)** — one search result ("Manage seats") + one editorial
      backlog item (missing subject `scim`). Changelog tile reads "Send"
      (`entrySeverity: 'major'` ≥ subscription `minSeverity: 'minor'`).
- [ ] **Populated (long)** — N/A; single-article seed; `maxResults: 5` caps
      search.
- [ ] **Error (recoverable)** — N/A; no query.
- [ ] **Error (unrecoverable)** — no custom handler; render throw → Next
      default.
- [ ] **Offline** — N/A (server-rendered).
- [ ] **Gated** — no session →
      `redirect('/unauthorized?reason=missing-session&returnTo=/help')`;
      middleware blocks unauthenticated requests upstream.
- [ ] **Standalone PWA** — N/A; no manifest. (verify.)

## Interactions

- [ ] **Summary tiles** (`styles.summaryItem` × 3) — display-only (Search
      results / Tooltips / Changelog Send|Skip); not focusable, no telemetry.
- [ ] **Help list items** (`styles.listItem` — search results + editorial
      backlog)
  - Function: render-only; search rows show `title` + `summary`, backlog rows
    show missing-subject keys. No search input, article opener, or feedback form
    exists in code — the query is hard-coded; this is a read-only resolved view.
  - Keyboard: list is not interactive.
  - Screen reader: list semantics; `<strong>` titles.
  - Touch target: N/A.
  - Mobile (≤ 640 px): `workspace.module.css` list styling.
  - Disabled when: N/A.
  - Offline behavior: N/A.
  - Telemetry: _None._

## Data & contracts

- **Reads / pure-function calls** (all from `@oshun/tenant-console`, hard-coded
  seed input, **no BFF call**):
  - `searchHelp({ articles, query })` → ranked `HelpArticle` results for the
    viewer context.
  - `resolveInProductHelp({ context, tooltips, walkthroughs, videos, articles })`
    → `{ tooltips, ... }` applicable to surface `/members`.
  - `aggregateFeedback([...])` → editorial backlog with `missingSubjectCounts`.
  - `shouldDeliverChangelog({ subscription, entrySeverity, entryLocale })` →
    boolean (severity/locale gating).
- **Writes**: _None._ (No feedback-submit surface in code.)
- **Realtime**: _None._
- **Caching**: SSR (dynamic; cookie read). Deterministic per tenant id.
- **Auth/role check**: `middleware.ts` + page `getTenantServerSession()` →
  `canEnterTenantShell`.

## Cross-references

- Domain logic: `libs/oshun/tenant-console/src/help-center/index.ts`
  (`searchHelp`, `resolveInProductHelp`, `aggregateFeedback`,
  `shouldDeliverChangelog`, `HelpArticle`).
- Workspace model: `libs/oshun/navigation/src/tenant-ia.ts` (`help`,
  `group: configuration`).
- Sibling routes: [home.md](./home.md), [content.md](./content.md),
  [agents.md](./agents.md). `/notifications` (channel prefs + templates) lacks a
  file yet.

## Open questions / known gaps

- [ ] Articles, tooltips, query, and feedback are hard-coded seed data; no BFF
      read of the knowledge base or feedback write path is wired. Document the
      eventual content source and feedback-submit endpoint.
- [ ] No search input or article reader UI — the page renders a fixed
      precomputed query. Confirm interactive help search is a later phase.
