Context. surface workspace · domain workspace (canonical shell-route alias / redirect) · route /app/[surface]/[[...path]] · auth anon (redirect-only; downstream route enforces auth) · source apps/oshun/web/src/proxy.ts; apps/oshun/web/src/app/app/[surface]/[[...path]]/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; content re-verified 2026-06-03 against current source; alias redirect contract re-verified 2026-06-30 with apps/oshun/web/e2e/canonical-deep-links.spec.ts and middleware-public-paths unit coverage
Purpose#
A redirect-only catch-all that maps /app/<surface>/<rest> to the canonical
shell route for <surface>. Used as a URL-stable alias so external links, push
notifications, deep links, and standalone-PWA launches can reference
/app/<surface> without baking in the canonical path (which may evolve). The
proxy resolves the alias before the auth gate so the alias itself stays
anonymous-accessible; the canonical downstream route still applies its own auth
and shell policy. The page component remains as the route-level fallback and
returns null after issuing the same redirect.
Entry points#
- PWA
start_url(permanifest.json) routes to/?surface=pwa, but/app/[surface]is the canonical-alias form used in deep links outside the app shell - Push notification deep links with surface-stable targets
- Marketing site linking into specific shell surfaces by name
/app/search/...rewrites —params.surface === 'search'maps to'explore'(search lives inside Explore)- Email / SMS deep links referencing surface by name rather than path
Layout regions#
None. The page returns null after issuing a server-side redirect().
States#
- Valid surface —
params.surfacematchesisWebShellRoute(home|explore|activity|library|profile|studio) or'search'(rewrites toexplore)- Behavior: build target URL via
WEB_SHELL_ROUTE_PATHS[targetSurface], append serialized search params +pathjoined;redirect(target)
- Behavior: build target URL via
- Unknown surface —
params.surfacenot in the allowlist → standardnot-found.tsxshell via proxy rewrite before auth. - No path segments —
params.pathempty; target is justWEB_SHELL_ROUTE_PATHS[targetSurface](+ search params if any) - Path segments present —
params.path = ['a','b']→targetParams.set('path', 'a/b'); appended to target as?path=a/b - Search params present — preserved via
toSearchParams(strings set; arrays appended) -
?surface=pwaquery (or any other key) — passed through to the target as a query param
Verified 2026-06-30 by canonical-deep-links.spec.ts against local web + BFF
dev servers: every V1 shell surface alias lands on its canonical route with
path/query preservation, search lands on Explore, studio lands in the admin
shell, and unknown aliases render the standard not-found page. The same
contracts are unit-covered in middleware-public-paths.test.ts, including the
anonymous-before-auth proxy redirect and raw Cache-Control: no-store header.
Interactions#
None visible. The route is a one-shot server redirect — no user- facing interaction. Users land here from external links and are immediately taken to the canonical shell route.
Data & contracts#
- Reads: none (no data fetch)
- Writes: none
- Realtime: none
- Caching: proxy redirect sends
Cache-Control: no-store; SW does not cache redirects per default policy - Auth/role check: the alias itself is anonymous-accessible because proxy
resolution runs before the auth gate — redirect target is whatever the
downstream shell route enforces (typically signed-in for
/,/explore,/activity,/library,/profile;/studioresolves to the admin shell)
Surface allowlist#
From apps/oshun/web/src/navigation/routes.ts (WEB_SHELL_ROUTE_PATHS):
| surface param | redirect target |
|---|---|
home |
/ |
explore |
/explore |
activity |
/activity |
library |
/library |
profile |
/profile |
studio |
/studio |
search |
/explore (rewrite) |
| anything else | notFound() → 404 page |
Note: isWebShellRoute is the canonical type guard. 'search' is rewritten to
'explore' as a special-case alias because search lives inside Explore in V1's
IA.
Cross-references#
- Shell:
shell/02-routing-layouts.md(catch-all routes section) - Sibling workspace route:
workspace-catchall.md - Canonical shell targets:
- Routes module:
apps/oshun/web/src/navigation/routes.ts(WEB_SHELL_ROUTE_PATHS,isWebShellRoute) - Manifest:
apps/oshun/web/public/manifest.json(start_url) - Feature spec:
V1/features.md
Open questions / known gaps#
- Document the external systems that link to
/app/<surface>/...so a future routes-module change (renaming or adding a shell surface) updates them in lock-step - Confirm whether unknown aliases yield the same UI as direct
notFound()from another route — verified 2026-06-30; proxy rewrites to/_not-foundand Playwright asserts the standard "Page not found" heading. - Verify cache headers on the redirect response — verified 2026-06-30; proxy
alias redirects set
Cache-Control: no-storeso the alias stays redirectable if shell routes move. - Should
'search'mapping to'explore'add a?focus=searchor similar hint? Today the path goes to/exploreas-is; the user may expect the search input to be focused on landing