Site Map
Hierarchical map of every page in the consumer app. Companion to user-guide.md (prose reference) and user-flows.md (step-by-step journeys).
Scope: consumer app only (ionic_frontend/). The admin dashboard is mapped in admin-site-map.md; the marketing landing is mapped in marketing-site-map.md.
Source of truth: ionic_frontend/src/router/index.ts. Regenerate this doc whenever a route is added, removed, or its guard changes. Render PNG export with cd docs_site && npm run docs:diagrams.
Legend
flowchart LR pub(["Public route"]):::public auth["Authenticated route"]:::authed gateGate / Guard:::gate redir["Redirect"]:::redirect classDef public fill:#e0f2fe,stroke:#0284c7,color:#0c4a6e classDef authed fill:#fef3c7,stroke:#d97706,color:#78350f classDef gate fill:#fce7f3,stroke:#be185d,color:#831843 classDef redirect fill:#e5e7eb,stroke:#6b7280,color:#1f2937
- Public —
meta.public: true. No Clerk session required. - Authenticated — guarded by
router.beforeEach. No session → redirected to/sign-in?redirect=…. - Gate — additional
beforeEnterorevaluateOnboardingGatemay redirect even authenticated users. - Redirect —
redirect:entry in the router, no component.
Site map
flowchart TD
Root["/"]:::redirect --> Dashboard
subgraph Public["Public surfaces — no auth"]
direction TB
SignIn(["/sign-in"]):::public
SignUp(["/sign-up"]):::public
SsoCallback(["/sso-callback"]):::public
PublicGoal(["/public_goal/:goalId"]):::public
DesignSystem(["/design-system"]):::public
InviteAccept(["/invite/:token"]):::public
AccountDeleted(["/account-deleted"]):::public
end
subgraph Gates["Auth-gated entry guards"]
direction TB
AuthGuardClerk session check:::gate
OnboardingGateevaluateOnboardingGate:::gate
ProfileGateevaluateProfileCompleteGate:::gate
end
subgraph Onboarding["Onboarding wizard"]
direction TB
WelcomeRedir["/welcome"]:::redirect --> WelcomeSlide
WelcomeSlide["/welcome/:slideId"]:::authed
end
subgraph Profile["Profile completion"]
direction TB
ProfileRedir["/profile/complete"]:::redirect --> ProfileSlide
ProfileSlide["/profile/complete/:slideId"]:::authed
end
subgraph Home["Home / daily loop"]
direction TB
Dashboard["/dashboard"]:::authed
CheckInRedir["/check-in"]:::redirect
Feed["/feed"]:::authed
end
subgraph Goals["Goals"]
direction TB
GoalsList["/goals"]:::authed
GoalCreate["/goals/create"]:::authed
GoalDetail["/goal/:goalId"]:::authed
end
subgraph Communities["Communities"]
direction TB
CommList["/communities"]:::authed
CommDetail["/communities/:id"]:::authed
Challenge["/communities/:id/challenges/:challengeId"]:::authed
end
subgraph Progress["Progress"]
direction TB
Achievements["/achievements"]:::authed
BadgesRedir["/badges"]:::redirect --> Achievements
Play["/play"]:::authed
end
subgraph Coach["Coach"]
direction TB
CoachPage["/coach"]:::authed
MeetCoach["/meet-coach"]:::authed
Enneagram["/enneagram-assessment"]:::authed
end
subgraph Account["Account & meta"]
direction TB
Settings["/settings"]:::authed
OurStory["/our-story"]:::authed
PublicProfile["/u/:username"]:::authed
AdminBridge["/admin"]:::authed
CheckoutSuccess["/checkout/success"]:::authed
NotificationHistory["/notifications"]:::authed
FeedbackRedir["/feedback"]:::redirect --> Settings
CheckoutCancelRedir["/checkout/cancel"]:::redirect --> Settings
CatchAll["/:pathMatch(.*)*"]:::redirect --> SignIn
end
SignIn --> SsoCallback --> AuthGuard
SignUp --> SsoCallback
AuthGuard --> OnboardingGate
OnboardingGate -- "first run" --> WelcomeSlide
OnboardingGate -- "onboarded" --> ProfileGate
ProfileGate -- "profile incomplete" --> ProfileSlide
ProfileGate -- "profile complete" --> Dashboard
CheckInRedir --> CoachPage
Dashboard --> Feed
Dashboard -. "urgent goal" .-> GoalDetail
Dashboard -. "coach modal" .-> MeetCoach
GoalsList --> GoalCreate
GoalsList --> GoalDetail
GoalDetail -. "share" .-> PublicGoal
CommList --> CommDetail --> Challenge
Settings -. "tabs" .-> MeetCoach
Settings -. "tabs" .-> Enneagram
classDef public fill:#e0f2fe,stroke:#0284c7,color:#0c4a6e
classDef authed fill:#fef3c7,stroke:#d97706,color:#78350f
classDef gate fill:#fce7f3,stroke:#be185d,color:#831843
classDef redirect fill:#e5e7eb,stroke:#6b7280,color:#1f2937

Route table
The authoritative list. Diff against grep -E "path:" ionic_frontend/src/router/index.ts after any router change.
Component-backed routes
| Path | Name | Component | Auth | Gate | User-guide section |
|---|---|---|---|---|---|
/sign-in | SignIn | SignIn.vue | public | — | §1 Creating your account |
/sign-up | SignUp | SignUp.vue | public | — | §1 Creating your account |
/sso-callback | SsoCallback | SsoCallback.vue | public | — | — |
/dashboard | Dashboard | Dashboard.vue | auth | onboarding | §2 Your dashboard |
/analytics | PersonalAnalytics | AnalyticsView.vue | auth | personal_analytics_enabled flag guard | — |
/feed | ActivityFeed | ActivityFeed.vue | auth | onboarding | §9 Feed and social |
/goals | Goals | Goals.vue | auth | onboarding | §4 Goals |
/goals/create | GoalCreate | GoalCreate.vue | auth | onboarding | §4 Creating a goal |
/goals/create/quiz | GoalDiscoveryQuiz | GoalDiscoveryQuizView.vue | auth | goal_quiz_enabled flag guard | — |
/goal/:goalId | goal | Goal.vue | auth | onboarding | §4 Goal detail page |
/communities | Communities | Communities.vue | auth | onboarding | §11 Communities |
/communities/:id | Community | Community.vue | auth | onboarding | §11 Community detail page |
/communities/:id/challenges/:challengeId | ChallengeLeaderboard | ChallengeLeaderboard.vue | auth | onboarding | §11 Communities |
/achievements | Achievements | Achievements.vue | auth | onboarding | §10 Achievements, XP, and ranks |
/events/:id | SeasonalEvent | SeasonalEventView.vue | auth | onboarding | — (v4.63 Phase 9 — behind seasonal_events_enabled; flag-off renders the same "not found" state as a bad link) |
/public_goal/:goalId | publicGoal | PublicGoal.vue | public | — | §4 Public goals |
/admin | AdminRedirect | AdminRedirect.vue | auth | onboarding | — (bridges to admin_dashboard SPA) |
/settings | Settings | Settings.vue | auth | onboarding | §15 Settings and profile |
/settings/connected-apps | ConnectedApps | ConnectedAppsView.vue | auth | — | — (v4.14 Phase 5 — Connected Apps list: connect/disconnect/pause/resume) |
/settings/connected-apps/:provider/mappings | ManageMappings | ManageMappingsView.vue | auth | — | — (v4.14 Phase 5 — Connected Apps mapping management) |
/settings/blocked | BlockedUsers | BlockedUsersPage.vue | auth | onboarding | §16 Blocked users |
/settings/import | DataImport | DataImportPage.vue | auth | data_import_enabled flag guard | — (v4.64 Phase 5 — CSV import: pick a file, review, commit, summary) |
/our-story | OurStory | OurStory.vue | auth | onboarding | — |
/checkout/success | CheckoutSuccess | CheckoutSuccess.vue | auth | onboarding | §14 Supporter tier |
/design-system | DesignSystem | DesignSystem.vue | public | — | — |
/coach | Coach | Coach.vue | auth | onboarding | §7 Meet your Coach |
/meet-coach | MeetCoach | MeetCoach.vue | auth | onboarding | §7 Meet your Coach |
/u/:username | PublicProfile | PublicProfile.vue | auth | onboarding | — |
/enneagram-assessment | EnneagramAssessment | EnneagramAssessment.vue | auth | onboarding | §7 Meet your Coach |
/coaching/type | EnneagramTypeDetail | EnneagramTypeDetail.vue | auth | onboarding | §7 Meet your Coach |
/play | Play | PlayView.vue | auth | onboarding | — |
/welcome/:slideId | WelcomeSlide | WelcomeView.vue | auth | meta.onboarding | §1 Onboarding |
/profile/complete/:slideId | CompleteProfileSlide | CompleteProfileView.vue | auth | evaluateProfileCompleteGate | — |
/allies | Allies | AlliesPage.vue | auth | ally-request-flow-enabled flag guard | — |
/allies/discover | AllyDiscover | AllyDiscoveryPage.vue | auth | ally-request-flow-enabled flag guard | — |
/allies/pending | AllyPendingInbox | PendingAllyRequestsPage.vue | auth | ally-request-flow-enabled flag guard | — |
/invite/:token | InviteAccept | PartnerInvitePage.vue | public | partner-invite-enabled | — |
/teams/new | CreateTeam | CreateTeamView.vue | auth | — | — |
/join-team/:code | JoinTeam | JoinTeamView.vue | public | — | — |
/team-home | TeamHome | TeamHomeView.vue | auth | — | — |
/team-settings (alias /teams/settings, the latter baked into CreateTeamView.vue's Stripe redirect) | TeamSettings | TeamSettingsView.vue | auth | — | — |
/team-leaderboard (alias /teams/leaderboard) | TeamLeaderboard | TeamLeaderboardView.vue | auth | teams_leaderboards flag guard | — |
/notifications | NotificationHistory | NotificationHistory.vue | auth | onboarding | — |
/account-deleted | AccountDeleted | AccountDeleted.vue | public | evaluateAccountDeletedGate — in-memory post-deletion flag only, set by the self-service deletion flow; unset (fresh boot, refresh, deep link) redirects to /sign-in | — (OBJ-3059 — terminal screen at the end of self-service account deletion, App Store Guideline 5.1.1(v)) |
Redirects (no component)
| Path | Target | Why |
|---|---|---|
/ | /dashboard | Default landing for signed-in users |
/badges | /achievements | Legacy URL alias |
/check-in | /coach | /check-in → /coach migration (PR #915); CheckIn.vue removed |
/feedback | /settings?tab=feedback | Deep-link into Settings feedback tab |
/checkout/cancel | /settings?tab=supporter | Stripe cancel → return to upgrade tab |
/welcome | /welcome/:slideId (resumes mid-flow via firstSlideId()) | Onboarding resume |
/profile/complete | /profile/complete/:slideId (about by default) | Profile-completion entry |
/:pathMatch(.*)* | /sign-in | Catch-all 404 → sign-in |
Total: 40 component-backed routes + 8 redirects = 48 entries in the routes array.
CI-enforced. Drift between this table and
router/index.tsfails the Route Drift workflow. Run locally withcd docs_site && npm run docs:check-routes.
Notes
- All authenticated routes also pass through
evaluateOnboardingGate. A user who has not finished onboarding is redirected to/welcome/:slideIdregardless of which route they hit. The welcome path itself is exempt (D-05 inrouter/index.ts) to prevent redirect loops. /profile/complete*has its ownbeforeEnterguard (evaluateProfileCompleteGate) that bounces users with already-complete profiles to/settings. This is the one route group that runs a second gate afterbeforeEach.- Admin role guard is hooked via
to.meta.requiredRole === 'admin'. No route currently sets it; admin-only surfaces live in the separateadmin_dashboard/SPA, mapped in admin-site-map.md./adminhere is a bridge that redirects users into that SPA. /u/:usernameis not flaggedpublicin the router despite being conceptually a public profile page. Signed-out visitors hitting it are sent to/sign-in. If public access is desired, addmeta: { public: true }.
For visual journeys through these routes (sign-up, daily check-in, goal lifecycle, coach setup), see user-flows.md.
Last updated: 2026-09-19 (footer currency fix, OBJ-4028 atlas sweep — a 3-run chronic gap; content last changed 2026-09-18, PR #3328, adding the /events/:id SeasonalEvent route row)