This guide defers to the V1 PWA walkthrough's
../WALKTHROUGH/00-conventions.md for
template, status legend, walking discipline, and file-naming rules. Read that
first.
The sections below define only the admin-specific differences.
Frontmatter values#
| Field | Admin-app values |
|---|---|
surface |
admin (one surface; no further split) |
domain |
The workspace group — governance / safety / content / operations / isis / cross-product / meta |
auth |
signed-in + admin-session for most routes; specific overrides for handoff (anon-with-customer-session-allowed) and unauthorized (anon). Workspace-specific scopes from OSHUN_ADMIN_WORKSPACE_MODEL.requiredScopes are listed in the frontmatter when restrictive. |
source |
apps/oshun/admin/src/app/<path>/page.tsx |
Auth state vocabulary#
The admin app has one cookie (OSHUN_ADMIN_SESSION_COOKIE_NAME) and a parsed
payload with scopes: string[]. Use these state names in checklists:
- anon — no admin session cookie present
- signed-in (admin) — valid admin session cookie;
parseAdminSessionTokenreturns a payload - signed-in (customer) — visiting
/handoffwith the customer session cookie but no admin session - signed-in (admin) + missing workspace scope — admin session but
canEnterAdminWorkspace(scopes, workspaceId)is false - rate-limited — too many requests per IP per minute (120)
The workspace pattern#
Most admin pages are thin server components:
export default async function FooPage(): Promise<JSX.Element> {
const session = await getAdminServerSession();
if (!session) {
redirect('/unauthorized?reason=missing-session&returnTo=/foo');
}
const [detail, operatorView] = await Promise.all([
loadWorkspaceDetail('foo', session),
fetchAdminOperatorView(session),
]);
return (
<AdminShell
session={session}
currentWorkspaceId="foo"
operator={operatorView.view}
>
<FooPanel detail={detail} />
</AdminShell>
);
}
When you walk a workspace page, focus the per-view file on what's unique to
that workspace — the panel(s) rendered inside AdminShell, their
interactions, the BFF workspace ID used. The shell chrome is covered in
shell/01-app-shell.md and shell/04-workspace-pattern.md — don't re-walk it
per file.
Cross-references rule#
The admin app references the V1 PWA walkthrough in two ways:
- Substrate links —
OSHUN_ADMIN_WORKSPACE_MODEL,loadWorkspaceDetail,AdminBffFetchResult, etc. live in@oshun/navigationand@/lib/*— link to the source files directly. - Operator V1 PWA equivalents — if an admin workspace mirrors a
/operator/*route in the V1 PWA (e.g., admin/inbox↔ V1 PWAoperator-admin.md), cross-link both directions.
Per-view template (mirrors the parent)#
---
path: /route
surface: admin
domain: governance | safety | content | operations | isis | cross-product | meta
auth: signed-in (admin) [+ scope:<scope>]
source: apps/oshun/admin/src/app/<path>/page.tsx
status: stub | drafted | walked | stale
last_walked: '—'
---
# Workspace · view name
## Purpose
## Entry points
## Layout regions
## States
## Interactions
## Data & contracts
## Cross-references
## Open questions / known gaps
Use _None._ for empty sections rather than removing them.
Walking discipline#
Same as the parent — run the admin app locally with a valid session, navigate to
the route as the auth role specified in the frontmatter, verify each state and
interaction, tick the box, set status: walked, and record
last_walked: <date> by <name>, against commit <sha>.
If a local development token is used instead of the privileged handoff, say so
in last_walked; do not present a dev-token walk as evidence for the production
handoff exchange.
The admin app's local dev environment requires:
- A privileged handoff to issue the admin session cookie (see
shell/03-auth-session.md). - BFF running locally so
loadWorkspaceDetailreturns workspace data. Without it, every workspace falls back toWorkspaceEntryPoint's "Workspace data unavailable" notice — many checks won't be walkable.