Skip to content

feat(onboarding): forced first-run onboarding + mobile-first shell - #35

Draft
EpicStarAi wants to merge 1 commit into
fix/operator-auth-guardfrom
feat/onboarding-and-shell
Draft

feat(onboarding): forced first-run onboarding + mobile-first shell#35
EpicStarAi wants to merge 1 commit into
fix/operator-auth-guardfrom
feat/onboarding-and-shell

Conversation

@EpicStarAi

Copy link
Copy Markdown
Owner

Base branch

Base: fix/operator-auth-guard (@ 97ab5d4) — the production-representative, security-hardened branch.

There is no qclaw-release-20260717-1130 git tag anywhere (local or origin). fix/operator-auth-guard = prod's backup/operator-ui-account-fetch (7659db4) plus the P0 auth guard (0f8fc93, closes unauthenticated /api/operator/* + drops client-trusted approval) and the middleware fix (97ab5d4). It is the compiling superset with a real resolveBoundAccount (not the stub some branches carry). Basing here keeps the security fixes and avoids weakening anything. Not main (main lacks the binding foundation).

feat/tg-like-client (#32) shares the same merge-base but lacks the P0 guard and is owned by another session, so it was not merged. This work is kept decoupled (see below) so it reconciles cleanly with either shell.

What & why

A first-time user used to drop straight into the client with zero explanation. This adds a forced, DB-backed onboarding and makes the shell usable on a phone (the owner uses it from a phone).

1. Forced onboarding — components/OnboardingGate.tsx

  • 5 plain-language steps: what EPIC GRAM is (a workplace, not a Telegram client) → operator does the routine but sends nothing without your confirmationApproval Gate (approve/reject + audit) → connect Telegramwhere operator/chats/missions live.
  • Reuses the existing TelegramBindingWizard for the connect step (steps aside to reveal it) — no duplicated auth UI.
  • Progress persists per-workspace in the DB (/api/onboarding/status), never localStorage. Forced until completed or skipped; re-openable from the menu ("Онбординг") or ?onboarding=1.
  • No fake success: if Telegram isn't connected, the flow states plainly that the system cannot act yet.

2. Store — mirrors the profile pattern

lib/onboarding.ts + onboardingDb.ts / onboardingStore.ts / onboardingData.ts; GET/POST /api/onboarding/status guarded by requirePrincipal; migrations/003_workspace_onboarding.sql (table also created idempotently at runtime).

3. Responsive shell — EpicGramShell.tsx

  • Operator panel: closed by default on mobile (behind the FAB), opens full-screen sheet; stays a 380px right side panel on desktop — no longer overlaps the chat.
  • <main> uses 100dvh + safe-area insets so the keyboard/notch don't cover the composer or FAB; the burger menu panel scrolls.
  • Section navigation from the reference (components/SectionNav.tsx): grouped Оператор / Организация / Производство / Маркетинг и аналитика / Инструменты / Инфраструктура. Sections with no real destination render as honest «готовится»no invented metrics, no demo mode (the reference's TON/USDT/Stars/mission counts are fiction and are not reproduced).

Security

No new mutations. TELEGRAM_MUTATION untouched. All data via existing authenticated APIs. The P0 auth guard from the base is preserved.

Verification

  • next build, tsc --noEmit, next lint, node --test — all green (5/5 tests pass).
  • Walked the flow on a candidate session (dev referral). Layout measured via DOM at 375px and 1280px:
    • Mobile 375×812: onboarding overlay covers full viewport; connect step shows the honest "not connected" copy; completion persists completed:true in the store; not re-forced on reload; menu relaunch reopens at 1/5; operator opens as full-screen 375×812 sheet; burger shows 6 groups + 8 «готовится».
    • Desktop 1280×800: 4-column grid (68px 380px 512px 320px); operator = 380px right panel at x=900, chat stays visible.
  • Screenshots: the preview-browser capture tool times out consistently in this environment (page renders fine, readyState: complete); DOM measurements above stand in as rigorous proof of the no-overlap/full-screen layout claims.

🤖 Generated with Claude Code

New users landed straight in the client with no explanation. This adds a
forced, DB-backed onboarding and makes the shell usable on a phone.

Onboarding (route-independent overlay <OnboardingGate/>):
- 5 plain-language steps: what EPIC GRAM is (a workplace, not a Telegram
  client), the operator does routine but sends nothing without approval,
  the Approval Gate, connect Telegram, where operator/chats/missions are.
- Connect step reuses the existing <TelegramBindingWizard/> by stepping
  aside — no duplicated auth UI.
- Progress persists PER WORKSPACE in Postgres (fs fallback), never in
  localStorage. Forced until completed or skipped; re-openable from the
  menu ("Онбординг") or ?onboarding=1. Honest: if Telegram is not
  connected it says the system cannot act — no fake success.

Store: lib/onboarding.ts + onboardingDb/Store/Data.ts mirror the profile
pattern; GET/POST /api/onboarding/status guarded by requirePrincipal;
migrations/003_workspace_onboarding.sql (also created idempotently at
runtime).

Responsive shell (EpicGramShell):
- Operator dock closed by default on mobile (behind FAB), full-screen
  sheet when opened; stays a 380px right side panel on desktop — no
  longer overlaps the chat.
- <main> uses 100dvh + safe-area insets so the keyboard/notch don't
  cover the composer or FAB; menu panel scrolls.
- Burger nav replaced with <SectionNav/>: reference-structured groups
  (Оператор/Организация/Производство/Маркетинг/Инструменты/Инфраструктура).
  Sections with no real destination render as honest "готовится" — no
  invented metrics, no demo mode.

Security unchanged: no new mutations, TELEGRAM_MUTATION untouched, all
data via existing authenticated APIs. build + typecheck + lint + tests
green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant