Tenant Admin Console · Surface walkthrough

Tenant admin handoff

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

drafted
8sections2 minread

On this page

Context. surface tenant-admin · domain meta · route /handoff · auth anon (public path — no tenant session required) · source apps/oshun/tenant-admin/src/app/handoff/page.tsx

Last walked.

Purpose#

Public bridge view explaining that the tenant cockpit needs a tenant-scoped session (tenant:admin:{tenantId} claim) and that the identity provider will issue one and redirect back. It is one of the two PUBLIC_PATHS in middleware.ts (with /unauthorized) and is reachable without a session.

Entry points#

  • /unauthorized "return to the handoff" link → /handoff?returnTo=<encoded path> (see help.md / middleware redirect chain).
  • Direct URL /handoff?from=<origin> (IdP-orchestrated landing after sign-in).
  • Listed in middleware.ts PUBLIC_PATHS so it renders pre-authentication.

Layout regions#

No TenantShell (anonymous, minimal page):

  • Main (<main data-testid="tenant-handoff-page">):
    • <h1>Tenant admin handoff</h1>
    • Paragraph: "You arrived from <strong>{from}</strong>" + explanation that the IdP issues a tenant:admin:{tenantId} claim and redirects back.
    • Paragraph with <Link href="/">Continue to tenant home →</Link>.

States#

  • Loading — N/A; synchronous server render; only reads searchParams.
  • Empty — when ?from is absent, from defaults to 'unknown' and the sentence reads "You arrived from unknown".
  • Populated (short)?from=<origin> renders the provided origin verbatim inside <strong>.
  • Populated (long) — N/A; single static paragraph regardless of params.
  • Error (recoverable) — N/A; no query.
  • Error (unrecoverable) — no custom handler; render throw → Next default.
  • Offline — N/A; static server-rendered page, no data.
  • Gated — N/A; public path. No session is read and none is required; middleware skips auth for /handoff.
  • Standalone PWA — N/A; no manifest. (verify.)

Interactions#

  • Continue to tenant home → (<Link href="/">)
    • Function: navigates to /. If the IdP has issued a valid oshun-tenant-session cookie, / renders; otherwise middleware redirects back to /unauthorized?reason=missing-session&returnTo=/.
    • Keyboard: standard link; Enter activates; in tab order.
    • Screen reader: announces "Continue to tenant home, link".
    • Touch target: inline text link — verify ≥ 44×44 px hit area on coarse pointers.
    • Mobile (≤ 640 px): inline; no layout delta.
    • Disabled when: never.
    • Offline behavior: standard navigation (no SW).
    • Telemetry: None.

Data & contracts#

  • Reads: searchParams ({ from?: string }) only. No session, no BFF call. Note: the /unauthorized link passes returnTo, but this page reads only fromreturnTo is ignored here.
  • Writes: None.
  • Realtime: None.
  • Caching: SSR (dynamic; depends on query params).
  • Auth/role check: none — middleware.ts PUBLIC_PATHS includes /handoff; no getTenantServerSession() call in the page.

Cross-references#

  • Middleware: apps/oshun/tenant-admin/src/middleware.ts (PUBLIC_PATHS).
  • Session issuance note: apps/oshun/tenant-admin/src/lib/session-cookie.ts (OSHUN_TENANT_DEV_TOKEN_PREFIX = 'tenant.'; operator equivalent at apps/oshun/bff/src/routes/admin-session.ts).
  • Sibling routes: /unauthorized (the other public path; no file requested), home.md.

Open questions / known gaps#

  • The page accepts ?from but the upstream /unauthorized link sends ?returnTo. Document whether from is ever populated by a real IdP flow, and whether returnTo should be honored on "Continue".
  • No actual IdP redirect is implemented in-app; the cookie is issued out of band (dev tenant. token). Document the production session-issuance path.