Context. surface customer · domain account · route /profile · auth signed-in · source apps/oshun/web/src/app/profile/page.tsx
Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md' '2026-06-27 Codex route-state addendum — default signed-in profile, noindex metadata, privacy/data-rights highlight deep links, loading/offline/partial outage/error shell fallbacks, standalone PWA restore, anonymous auth gate, sign-out affordance, and upgrade-intent billing card are covered by the E2E references below.' '2026-06-28 Codex shortcut-map addendum — every account shortcut href and WebProfileRoutePath highlight target is enumerated here and verified in profile-settings-flows.spec.ts against the real /profile route.
Purpose#
The signed-in user's account hub — "your account, billing, privacy, devices, and
what OSHUN remembers." Renders inside the standard ShellLayout with
active="profile", composing the ProfileSettingsPanel plus the shared
shell-route surface content resolver. Used as the landing for profile deep-links
and as the host for shell-driven upgrade intents.
Entry points#
- Shell nav: Profile (
active="profile") - Direct URL / bookmark — yes (auth required)
- Upgrade-intent deep link:
?intent=<intent>&domain=<id>&requiredTier=<tier>surfaces an upgrade-intent context toProfileSettingsPanel - Sub-route deep link: any
WebProfileRoutePathresolved byresolveWebProfileRoutePath(searchParams)(e.g., billing, devices, privacy, account — each highlights a specific row) - Cross-domain settings deep links (e.g., from
/aaa-upgrade) - Sign-out / sign-in confirmation handoff
Layout regions#
page.tsx mounts <ShellLayout active="profile" breadcrumbs=[Home, Profile]>
and inside it calls
resolveShellRouteSurfaceContent({ surface: 'profile', searchParams, children: <ProfileSettingsPanel highlightPath={highlightPath} upgradeIntent={upgradeIntent} /> })
— the resolver handles offline / fallback / unavailable framings, falling
through to the panel as children when the surface is healthy.
- Shell header: standard shell header with Profile active
- Breadcrumbs: Home → Profile (passed in via
ShellLayoutprop) - Surface resolver wrapper:
resolveShellRouteSurfaceContentdecides whether to render the profile panel or a shell-route fallback (offline / unavailable / reason) - ProfileSettingsPanel: the actual settings UI (account, billing, privacy,
devices, memory, etc.) — composition lives in
apps/oshun/web/src/components/ProfileSettingsPanel.tsx. The panel useshighlightPathto open / accent a specific row andupgradeIntentto surface an inline upgrade context
States#
- Loading — handled by the resolver / panel; no explicit
loading.tsxat this segment - Default (no params) — full settings panel renders
- Highlight path —
searchParams.path(or equivalent) resolves viaresolveWebProfileRoutePath; the panel accents the matching sub-section - Upgrade intent active — when
intent,domain, orrequiredTierare present, the panel renders an upgrade-intent context above (or inside) the relevant row - Offline — shell-route resolver returns the offline fallback
- Unavailable / reason — shell-route resolver returns partial outage, degraded, retry, and missing-segment fallbacks for the profile surface
- Error (recoverable) — resolver error state keeps profile inside the shell with primary and secondary recovery affordances; row-level profile validation errors remain panel-owned and are covered by the relevant interaction specs
- Anonymous user — middleware redirects to
/welcome - Standalone PWA — shell restores
/profilefrom standalone launch and keeps the mobile nav within the viewport
Interactions#
Interactions live inside ProfileSettingsPanel; the page itself only wires
highlight + upgrade-intent state. Current route-state coverage is:
apps/oshun/web/e2e/profile-settings-flows.spec.ts— signed-in default profile, canonical/noindex metadata, privacy/data-rights highlight routing, full account shortcut href + highlight-target matrix, loading/offline/ partial-outage/error resolver cards, standalone PWA restore, profile writes, preferences, data export, and legal navigationapps/oshun/web/e2e/profile-channel-bindings.spec.ts— "Notification channels" email/SMS binding lifecycle on the real/profilesurface: address/code issue, BFF read-back, route reload persistence, revoke read-back, wrong-code non-verification, and 390 px 44 px/no-overflow controls with the real service worker enabledapps/oshun/web/e2e/shell-surface-states.spec.tsandapps/oshun/web/e2e/shell-route-signoff.spec.ts— exhaustive shell fallback matrix for the profile surface across loading, empty, offline, partial outage, degraded, retry, partial response, and error statesapps/oshun/web/e2e/customer-paywall-upgrade-surfaces.spec.ts—/profilebilling upgrade intent for free/pro/premium entitlement states and the no-intent controlapps/oshun/web/e2e/auth-entry-flows.spec.ts— anonymous/profileredirect, signup/onboarding handoff back to/profile, and sign-out control coverage
Surface-resolver framing#
- Offline framing — surfaces a network-issue message instead of the panel
- Unavailable framing — surfaces partial outage / degraded shell recovery copy and trace/missing-segment notes instead of the panel
Highlight target (panel-level)#
- Highlight row open/accent — when
highlightPathis set, the panel opens and accents the corresponding row (account / billing / devices / privacy / memory / safety etc.)
Upgrade-intent context (panel-level)#
- Upgrade intent banner — when any of
intent,domain,requiredTieris set, the panel surfaces an in-context upgrade affordance referencing the intent
Sub-route navigation#
ProfileSettingsPanel exposes the account shortcut rail
(data-profile-account-links) with this route/highlight contract:
| Shortcut label | Hook id | Href | Highlight result |
|---|---|---|---|
| Account | account |
/profile?path=account |
Account shortcut active; no section |
| Activity & stats | stats |
/profile?path=stats |
Domain statistics section force-open |
| Plans & billing | billing |
/profile?path=billing |
Plans and billing section force-open |
| Personalization | personalization |
/profile?path=personalization |
Personalization section force-open |
| Privacy & access | privacy |
/profile?path=privacy |
Privacy and access section force-open |
| Data rights | data-rights |
/profile?path=data-rights |
Data requests section force-open |
| Devices & sessions | sessions |
/profile?path=sessions |
Devices & sessions section force-open |
| Operator access | operator-access |
/profile?path=operator-access |
Operator access section force-open |
The resolver also accepts alias-only highlight values that do not have rail
shortcuts: billing-support → billing, preferences → personalization,
assistant / assistant-controls / memory → Assistant and memory,
notifications → Notifications, calendar / calendar-sync → Calendar sync,
consent / consent-controls → Consent center, and onboarding /
onboarding-setup → Onboarding setup.
Data & contracts#
- Reads:
resolveWebProfileRoutePath(searchParams)→WebProfileRoutePath | undefinedWEB_SHELL_ROUTE_PATHS.homefor the breadcrumbProfileSettingsPanelreads BFF account/billing/devices endpoints (verify exact list on walk)
- Writes: panel-driven (account update, billing, devices, etc.)
- Realtime: device sessions list may subscribe to a session feed (verify)
- Caching: SSR shell; SWR within the client panel
- Auth/role check: signed-in; middleware enforces
- Metadata:
title: 'Profile',description: 'Your account, billing, privacy, devices, and what OSHUN remembers.',robots: { index: false, follow: false },alternates.canonical: '/profile'
Cross-references#
- Shell:
shell/01-app-shell.md,shell/04-auth-session.md - Sub-routes:
- Upgrade flow:
../13-system/aaa-upgrade.md - E2E coverage:
apps/oshun/web/e2e/profile-settings-flows.spec.tsapps/oshun/web/e2e/profile-channel-bindings.spec.tsapps/oshun/web/e2e/shell-surface-states.spec.tsapps/oshun/web/e2e/shell-route-signoff.spec.tsapps/oshun/web/e2e/customer-paywall-upgrade-surfaces.spec.tsapps/oshun/web/e2e/auth-entry-flows.spec.ts
- Component sources:
apps/oshun/web/src/components/ProfileSettingsPanel.tsxapps/oshun/web/src/components/ShellLayout.tsxapps/oshun/web/src/app/shellRouteState.tsapps/oshun/web/src/navigation/routes.ts
Open questions / known gaps#
- Enumerate every settings row exposed by
ProfileSettingsPaneland map toWebProfileRoutePathhighlight values — the shortcut matrix above is backed byprofile-settings-flows.spec.ts, and alias-only highlight values are documented separately. - Document the full set of supported
intentvalues forupgradeIntentand their tier-requirement mapping - Confirm whether the panel exposes a sign-out affordance here or relies on
the shell header — the panel exposes
data-profile-signout-btn, covered inauth-entry-flows.spec.tsandshared-shell-entry-routes.spec.ts - Confirm device-session realtime updates
- Document offline behaviour for in-flight settings edits