Skip to main content

Flow Diagrams

Three maps: what changes (outcome), how value flows (stream), and where users navigate (architecture).

Outcome Map

What changes when this ships?

Before

Sign inClerk authenticates user
ResolveAuth adapter queries system_user.limit(1) — picks first org
RouteRedirect to /(app)/dashboard — no org in URL
RenderAll data from first org. Solar365 sees Dreamineering's CRM.

After

Sign inClerk authenticates user
CountCheck user org memberships: 0 → /setup, 1 → auto-redirect, 2+ → picker
RouteRedirect to /org/[slug]/dashboard — org in URL
GuardLayout validates slug → org ID → user membership
RenderApplicationContext.organizationId from URL. Solar365 sees only Solar365.

Value Stream

Where does the value flow — and where does it stop?

INPUTUser signs in via Clerk. Has externalAuthId.
LOOKUPQuery system_user rows for this externalAuthId. Returns 0-N org memberships.
ROUTE0 orgs → /setup. 1 org → /org/[slug]/. 2+ orgs → /organisations/select.
GUARDLayout at /org/[slug]/ resolves slug to org ID. Validates user is member. Sets ApplicationContext.
RENDERChild routes inherit org context. Server actions receive organisationId from context. Data scoped.
SWITCHOrg switcher in nav. Click different org → navigate to /org/[other-slug]/dashboard. No re-auth.
LEGACYOld /dashboard URLs catch-all redirect to /org/[primary-slug]/dashboard.

Value stops if: the GUARD step fails open (renders without validating membership) or the auth adapter ignores the URL slug and falls back to DB default. Both are cross-tenant exposure.

Navigation Architecture

How does the user move through the system?

StageQuestionAnswer
PainWhat hurts today?Sign in, see wrong org's data. Cannot demo to prospects.
AwarenessHow do they discover?URL changes to /org/[slug]/. Org name visible in nav header.
First ValueSmallest proof?Sign in → land on correct org dashboard → see only your contacts.
HabitHow does it stick?Bookmarks include org slug. Org name always visible. No ambiguity.
MasteryPower user flow?Org switcher in nav. Switch orgs without re-auth. Deep links preserved.
EffortlessSystem reduces effort?Single-org users never see picker. Last-used org remembered.

Route Structure

/(public)/sign-in
/(public)/organisations/select
/(public)/setup
/(app)/org/[slug]/dashboard
/(app)/org/[slug]/crm/*
/(app)/org/[slug]/rfp/*
/(app)/org/[slug]/plans/*
/(app)/org/[slug]/settings/*
/(app)/org/[slug]/insights/*
/(app)/org/[slug]/calendar/*
/(app)/dashboard → redirect to /org/[primary-slug]/dashboard
/(app)/crm/* → redirect to /org/[primary-slug]/crm/*