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
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# 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.ts`** — `transpilePackages` 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.
|
||||
Reference in New Issue
Block a user