| 03-operator-experience |
02 |
ui |
| slack |
| oauth |
| whatsapp |
| onboarding |
| byo-keys |
| nextjs |
| react-hook-form |
| tanstack-query |
| shadcn-ui |
|
| phase |
plan |
provides |
| 03-operator-experience |
01 |
Slack OAuth endpoints, WhatsApp connect endpoint, channel test endpoint, LLM key CRUD endpoints (Plan 01) |
|
|
| Slack OAuth callback route handler at /api/slack/callback |
| Onboarding wizard page at /onboarding (3-step stepper via URL searchParams) |
| OnboardingStepper component with numbered steps, active/completed/pending states |
| Step 1 - ConnectChannel |
| Slack OAuth button + WhatsApp manual form with step-by-step instructions |
|
| Step 2 - ConfigureAgent |
| agent list with Agent Designer link, Next enabled only with active agent |
|
| Step 3 - TestMessage |
| per-channel Send Test Message buttons, required step, no Go Live button |
|
| BYO API Key settings page at /settings/api-keys (list, add, delete with confirmation) |
| TanStack Query hooks |
| useSlackInstallUrl, useConnectWhatsApp, useSendTestMessage, useChannelConnections, useLlmKeys, useAddLlmKey, useDeleteLlmKey |
|
| API types |
| SlackInstallResponse, ChannelConnection, WhatsAppConnectRequest/Response, TestMessageResponse, LlmKey, LlmKeyCreate |
|
| API Keys link in sidebar nav |
|
| 03-03 (billing UI — shares the same nav, portal patterns) |
| 03-04 (cost dashboard — same portal conventions) |
|
| added |
patterns |
| recharts (was in package.json but not installed — installed to unblock portal build) |
|
| Onboarding wizard step state via URL searchParams (step=1|2|3) — shareable/refreshable |
| Auto-advance on successful channel connect (1500ms delay + router.push) |
| Slack OAuth |
| fetch install URL from backend, then window.location.href redirect to Slack |
|
| WhatsApp |
| inline expandable form with humanized step-by-step credential instructions |
|
| BYO key display pattern |
| show ...{key_hint} (last 4 chars) — never plaintext |
|
| Dialog for add form and delete confirmation using @base-ui/react Dialog pattern |
|
|
| created |
modified |
| packages/portal/app/api/slack/callback/route.ts |
| packages/portal/components/onboarding-stepper.tsx |
| packages/portal/app/(dashboard)/onboarding/page.tsx |
| packages/portal/app/(dashboard)/onboarding/steps/connect-channel.tsx |
| packages/portal/app/(dashboard)/onboarding/steps/configure-agent.tsx |
| packages/portal/app/(dashboard)/onboarding/steps/test-message.tsx |
| packages/portal/app/(dashboard)/settings/api-keys/page.tsx |
|
| packages/portal/lib/api.ts (added channel and LLM key types) |
| packages/portal/lib/queries.ts (added 7 new hooks) |
| packages/portal/components/nav.tsx (added API Keys nav link) |
|
|
| Agent goes live automatically after test message — is_active is true by default, no separate Go Live button (per user decision) |
| Test message step is REQUIRED — no skip button (per user decision) |
| BYO API keys are tenant-level (v1 simplicity) — page reads tenant_id from searchParams |
| Onboarding wizard uses URL searchParams for step state — step=1|2|3 makes URLs shareable and browser-back friendly |
| Slack OAuth redirect: window.location.href = authorize_url — NOT router.push, Slack must redirect the actual browser tab |
| Portal git initialized as submodule with its own .git repo — enables atomic per-task commits in portal |
|
| Submodule commit pattern: portal files committed inside packages/portal .git, then parent repo git add packages/portal to update gitlink |
| Onboarding stepper: numbered circles + connector lines, completed steps show Check icon, active step shows ring-primary |
| WhatsApp form: expandable card pattern — Button to expand, form appears inline, Cancel collapses |
|
|
~35min |
2026-03-23 |