feat(onboarding): forced first-run onboarding + mobile-first shell - #35
Draft
EpicStarAi wants to merge 1 commit into
Draft
feat(onboarding): forced first-run onboarding + mobile-first shell#35EpicStarAi wants to merge 1 commit into
EpicStarAi wants to merge 1 commit into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Base branch
Base:
fix/operator-auth-guard(@ 97ab5d4) — the production-representative, security-hardened branch.There is no
qclaw-release-20260717-1130git tag anywhere (local or origin).fix/operator-auth-guard= prod'sbackup/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 realresolveBoundAccount(not the stub some branches carry). Basing here keeps the security fixes and avoids weakening anything. Notmain(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.tsxTelegramBindingWizardfor the connect step (steps aside to reveal it) — no duplicated auth UI./api/onboarding/status), never localStorage. Forced until completed or skipped; re-openable from the menu ("Онбординг") or?onboarding=1.2. Store — mirrors the
profilepatternlib/onboarding.ts+onboardingDb.ts/onboardingStore.ts/onboardingData.ts;GET/POST /api/onboarding/statusguarded byrequirePrincipal;migrations/003_workspace_onboarding.sql(table also created idempotently at runtime).3. Responsive shell —
EpicGramShell.tsx<main>uses100dvh+ safe-area insets so the keyboard/notch don't cover the composer or FAB; the burger menu panel scrolls.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_MUTATIONuntouched. 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).completed:truein 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 «готовится».68px 380px 512px 320px); operator = 380px right panel at x=900, chat stays visible.readyState: complete); DOM measurements above stand in as rigorous proof of the no-overlap/full-screen layout claims.🤖 Generated with Claude Code