All docs/Hello

docs/architecture/hello-vs-library-user-flow.md

Hello App to Library App User Flow

Last verified: 2026-03-03 Target: apps/helloapps/library

This document describes the complete user journey from anonymous video flow creation in the Hello app through authentication and into the Library app.

Overview

The Hello app serves as the onboarding entry point where users create video interviewers anonymously as drafts. Publishing is deferred until after authentication — no flow is created until the user has signed up/in and the draft is converted to a FlowConfig and published directly to the user's organization.

Demo App: For demonstrating these flows without authentication, see the standalone apps/demo which consolidates demo pages from both Hello and Library apps. See Demo App and Tier Architecture.

High-Level Flow

Detailed Authentication & Publish Flow

The Hello app uses a deferred publish pattern. Drafts live in Redis and are only converted to published FlowConfig records after the user authenticates.

Key Design Decisions

  1. Deferred Publish: Flows are NOT published until the user is authenticated. The OnboardingDraft lives in Redis, and the draftId in the URL is the only state needed to resume.

  2. No Flow Cookies: The old hc_pending_flow cookie and claim-based flow have been removed. The draft auth cookie (HMAC-signed) only authorizes access to a specific draft — it does not store flow IDs.

  3. No Intermediate Organization: Flows are published directly to the user's organization. There is no "hello org" staging step.

  4. Automatic Org Creation: New signups with no organizations get one created automatically from the draft's organizationProfile (company name, logo).

  5. Multi-Org Selection: Users with multiple organizations see an OrgPickerForm before publishing.

Authentication Redirect Handling

Different auth methods have different redirect mechanisms back to the publish page:

Auth MethodRedirect MechanismKey File
OAuth (Google, Microsoft)sso-callback/page.tsx sets signUpForceRedirectUrlapps/hello/app/d/[draftId]/publish/sso-callback/page.tsx
Email/PassworduseAuth() watcher in AuthGateForm detects isSignedIn and does window.location.hrefapps/hello/components/steps/AuthGateForm.tsx
Direct page load (already authenticated)[...rest]/page.tsx catch-all redirects to /d/[draftId]/publishapps/hello/app/d/[draftId]/publish/[...rest]/page.tsx

Why email/password needs special handling

Clerk Elements (SignUp.Root, SignIn.Root) with routing="path" manage their own sub-step navigation (e.g., /publish/continue, /publish/verifications). After the sign-up flow completes, Clerk redirects to the global NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL rather than back to the component's path prop. Since this global URL is typically / (the root page), the user would end up on the wrong page.

The AuthGateForm component intercepts this by watching useAuth().isSignedIn and performing a full page load (window.location.href) to /d/[draftId]/publish when auth completes. This triggers the PublishPage server component which handles publishing and redirects to Library.

Hello App Entry Points

The root page (apps/hello/app/page.tsx) handles the decision tree for returning vs new users:

The /start page also checks for an existing unpublished draft (via cookie) and offers a resume prompt. In ?demo mode, both the resume prompt and the saved-company card are suppressed — ideal for demos and screen recordings.

Key Components

1. PublishPage (apps/hello/app/d/[draftId]/publish/page.tsx)

Server component that orchestrates the entire post-auth publish flow:

  • Validates draft auth cookie
  • For authenticated users: determines org count and publishes or shows picker
  • For unauthenticated users: renders AuthGateForm

2. AuthGateForm (apps/hello/components/steps/AuthGateForm.tsx)

Client component showing OAuth buttons and email/password forms:

  • Uses Clerk Elements (SignUp.Root, SignIn.Root) with routing="path"
  • Watches useAuth().isSignedIn to redirect after email/password auth
  • Sub-steps handled by catch-all [...rest]/page.tsx route

3. usePublishFlow (apps/hello/hooks/usePublishFlow.ts)

Client hook used in the Studio step:

  • If user is signed in: publishes directly via publishDraftAction, handles multi-org picker
  • If user is not signed in: navigates to /d/{draftId}/publish for deferred publish

4. OrgPickerForm (apps/hello/components/steps/OrgPickerForm.tsx)

Client component for multi-org users to select which organization to publish to.

5. WelcomeBackClient (apps/hello/app/WelcomeBackClient.tsx)

Client component for returning authenticated users with existing organizations. Offers:

  • Go to dashboard (Library app)
  • Create a new flow from scratch (navigates to /start)

Library App Entry Points

After publishing, users land in the Library app with ?flowId=xxx parameter. The root page (/) checks for a flowId query param and redirects if present:

// apps/library/app/(main)/page.tsx
if (flowId) {
  redirect(`/dashboard/${flowId}`);
}
// Otherwise: show unified InterviewsView for all tiers
  • All organizations (any plan): Routed to the root /, which shows InterviewsView — a unified card grid of all interviews.
  • Deep-linked with ?flowId: Redirected directly to /dashboard/[flowId].

Architecture change (2026-02): The library root no longer forks by plan tier. Previously there were separate free/paid routes; now all users see the same InterviewsView. Plan-gating has moved to the respondent detail page: free users who don't own the video are redirected back to the flow dashboard. The legacy /onboarding route now redirects to root for backwards compatibility.

Environment Variables

Required for this flow:

  • LIBRARY_APP_URL: Where to redirect after publishing (e.g., https://library.thehappyclient.com)
  • NEXT_PUBLIC_CLERK_*: Clerk authentication configuration

Error Handling

  • If publish fails, an error page is shown with a "Go back" link to the design step
  • If draft is missing or auth cookie is invalid, user is redirected to /
  • If the draft was already published, user is redirected directly to Library with the existing flowId

Related Documentation