Tenant Admin Console · Surface walkthrough

Integrations

A per-surface walkthrough of the Tenant Admin Console tenant-admin surface: layout, states, interactions, data, and cross-references.

drafted
8sections3 minread

On this page

Context. surface tenant-admin · domain integrations · route /integrations · auth signed-in + tenant:admin (getTenantServerSession) · source apps/oshun/tenant-admin/src/app/integrations/page.tsx

Last walked.

Purpose#

Tenant-scoped read-only cockpit for the integrations workspace: shows API-key authentication results, outbound webhook subscription matching, dead-letter replay status, and connector health / error-budget / version-pinning — all computed for the signed-in tenant. Backs the integrations workspace (configuration group) in libs/oshun/navigation/src/tenant-ia.ts.

Entry points#

  • Shell sidebar (TenantSidebar) — "Integrations" (shortLabel) under the Configuration group, link to /integrations (data-workspace-id="integrations")
  • Workspace grid on / (home) — list item data-workspace-id="integrations" (text only; not a link)
  • Direct URL /integrations (bookmarkable; middleware-gated)

Layout regions#

Inside TenantShell (TenantSidebar left, TenantHeader top, <main id="tenant-main">):

  • Header: TenantHeader shows tenant · <tenantId> › workspace label "Integrations" (getOshunTenantWorkspaceDefinition('integrations').label)
  • Main: <section data-testid="tenant-integrations-panel" data-tenant-id={tenantId}>
    • <h1>Integrations</h1> + subtitle paragraph
    • .summaryGrid — four .summaryItem tiles: API key auth, Webhook matches, Replay status, Circuit
    • .table — connector table: columns Connector, Version, Error budget, Health

States#

  • Loading — N/A; server component renders fully-resolved fixture data in one pass (no client fetch, no skeleton)
  • Empty — N/A; data is a hardcoded in-page fixture (single connector Canvas LMS), never empty
  • Populated (short) — exactly one connector row + four summary tiles always render (auth.authenticated → "Accepted", matchingSubscriptions length, replay.status, circuit.state)
  • Populated (long) — N/A; fixture is fixed-size (1 connector)
  • Error (recoverable) — N/A; no runtime query to fail
  • Error (unrecoverable) — no session → redirect('/unauthorized?reason=missing-session&returnTo=/integrations')
  • Offline — N/A for data (SSR-rendered); shell chrome served from cache if SW present (verify: no SW registered in this app)
  • GatedgetTenantServerSession() returns null (missing/invalid/expired token, or scopes fail canEnterTenantShell) → redirect to /unauthorized; sidebar renders this workspace Locked when canEnterTenantWorkspace is false (currently never, since all workspaces share the shell scope)
  • Standalone PWA — verify; layout sets themeColor #0f172a, no manifest confirmed in source

Interactions#

The page itself exposes no buttons, inputs, or links in <main> — it is a static read-only report. All interactivity is shell chrome:

  • Skip to main content (link, TenantShell)
    • Function: anchors to #tenant-main
    • Keyboard: first focusable element; Enter/Space activates
    • Screen reader: announces "Skip to main content"
  • Sidebar workspace links (links, TenantSidebar)
    • Function: navigate to each accessible workspace path; current item carries aria-current="page"; inaccessible items render as <span aria-disabled="true"> with a Locked tag
    • Screen reader: announces shortLabel (+ "Locked" when gated)
  • Connector / summary cells — non-interactive text/code/badge output; no controls

Data & contracts#

  • Reads: no BFF/network read. The page calls pure functions from @oshun/tenant-console on in-page fixtures:
    • authenticateApiKey({ providedTokenHash, providedIp, key: ApiKey, nowUnixSeconds })auth.authenticated
    • subscriptionsForEvent([WebhookSubscription], event) → matching count
    • replayDelivery({ delivery: WebhookDelivery, nowUnixSeconds })replay.status
    • evaluateCircuitBreaker({ connector: ConnectorRegistration, nowUnixSeconds })circuit.state
    • NOW is a frozen constant Date.UTC(2026, 4, 11, 15) (seconds)
  • Writes: None.
  • Realtime: None.
  • Caching: SSR (server component); fixture is deterministic so output is stable per tenantId
  • Auth/role check: page calls getTenantServerSession() (apps/oshun/tenant-admin/src/lib/server-session.ts); middleware (src/middleware.ts) redirects unauthenticated non-public paths to /unauthorized

Contracts: ApiKey, ConnectorRegistration, WebhookDelivery, WebhookSubscription from @oshun/tenant-console (libs/oshun/tenant-console).

Cross-references#

Open questions / known gaps#

  • Page renders a static fixture, not the live tenant integrations registry — no real API-key/webhook/connector BFF endpoint is wired (V1 placeholder). Document the eventual BFF route once integrations data is wired tenant-side.
  • No empty / error / long states are reachable until live data replaces the fixture.
  • Verify whether a PWA manifest / service worker exists for tenant-admin (none found in src/).