Files
lynkeduppro-crm/docs/APPSHELL_INTEGRATION.md
tanweer919 1d37593102 feat(appshell): integrate @abe-kap/appshell-sdk (strangler, mock fallback)
Wire the AppShell SDK for auth/identity across the CRM, gated behind
isShellConfigured() so the existing mock portal + static demo user stay
the fallback until the Shell BFF is configured.

- providers.tsx: app-wide <AppShellProvider> (auth passed only when Supabase env set)
- next.config.ts: transpilePackages + /shell -> BFF rewrite (keeps /api/geo intact)
- login: password -> login(), social -> loginWithOAuth(), OAuth return -> completeOAuthLogin()
- register: email/password sign-ups call register() on finish
- dashboard: AuthGate bounces unauthenticated visitors; topbar shows ACE identity
- docs/APPSHELL_INTEGRATION.md, .env.local.example, .npmrc for GitHub Packages
2026-07-09 20:51:17 +05:30

3.1 KiB

AppShell integration (lynkeduppro-crm)

This app now consumes @abe-kap/appshell-sdk for authentication, identity, and (eventually) the data door. The integration follows a strangler pattern: the SDK is wired in everywhere, but every real call is gated behind isShellConfigured(). When the Shell isn't configured (no NEXT_PUBLIC_SUPABASE_URL), the app behaves exactly as before — the existing mock portal and static demo user remain the fallback, so the deployed demo keeps working until the Shell BFF is live.

What flips it on

Set these (see .env.local.example) and redeploy:

Var Purpose
NEXT_PUBLIC_SUPABASE_URL Presence flips the app from mock → real auth (the isShellConfigured() switch).
NEXT_PUBLIC_SUPABASE_ANON_KEY Browser-safe publishable anon key.
NEXT_PUBLIC_BFF_BASE_URL Where the browser reaches the BFF (default /shell).
BFF_ORIGIN Deployed Shell BFF origin; the /shell/* rewrite proxies here.
NODE_AUTH_TOKEN read:packages token to install the SDK from GitHub Packages (local + Vercel).

How it's wired

  • src/app/providers.tsx — mounts <AppShellProvider> app-wide (via the root layout). auth is passed only when Supabase is configured; otherwise the provider mounts without auth and useAuth() reports unauthenticated (never crashes).
  • next.config.tstranspilePackages for the SDK + a /shell/* → ${BFF_ORIGIN}/api/* rewrite so the HttpOnly session cookie flows same-origin. We use /shell (not /api) to avoid clobbering the existing /api/geo route.
  • Login (components/portal/login-flow.tsx) — password sign-in → login(), social buttons → loginWithOAuth() (google/microsoft→azure/apple), and the OAuth return is finished with completeOAuthLogin(). A resolved ACE goes straight to /dashboard (Supabase handles MFA server-side; no mock 2-step).
  • Register (components/portal/register-flow.tsx) — email/password sign-ups call register() on finish. (SSO sign-ups already hold a session from OAuth.)
  • Dashboard gate (components/dashboard/auth-gate.tsx) — bounces unauthenticated visitors to the portal; pass-through when the Shell is off.
  • Topbar (components/dashboard/topbar.tsx) — shows the real identity from the App Context Envelope (useAuth().user), falling back to the static demo user.

Local build note

next build needs Node ≥ 20.9. Installing the SDK needs a GitHub Packages token; for a token-free local build you can symlink the workspace copy:

mkdir -p node_modules/@abe-kap
ln -s /abs/path/to/appshell-sdk node_modules/@abe-kap/appshell-sdk

Not yet wired (follow-ups)

  • Register-via-OAuth still uses the mock startSocial (login OAuth is real).
  • Email/phone OTP steps in register are still mock (SDK has sendEmailOtp/verifyEmailOtp).
  • Passkey enrollment, tenant switcher, logout menu, and the data door (useQuery/ command) are available in the SDK but not surfaced in the UI yet.
  • Backend integration (frontend ↔ be-crm through the data door) is deliberately deferred.