A self-paced onboarding track that introduces a new employee to every KB theme in breadth (not depth), so they grasp how Respellion works day to day and week to week. Offered as a CTA inside the Dashboard "New here?" explainer card; always available regardless of enrollment. Design: - Theme is the trackable unit; the 5 "days" are a read-time presentation grouping, so re-chunking never loses progress. Completion is stored per theme in onboarding_completions. - Per-theme overview generated lazily on first open (fast-tier emit_onboarding_overview tool), cached in onboarding_overviews keyed by theme + a topics_fingerprint that triggers regeneration when the theme's topic set changes. - Reachable via /onboarding-track using the existing skipEnrollmentGate prop, decoupled from the 26-week curriculum (distinct from /onboarding, the enrollment page). Backend: - pb_migrations/1781200000_created_onboarding.js: two collections with authenticated-only rules and unique indexes; TEXT team_member_id (no relation) per the post-#18/#27 convention. Mirrored in scripts/setup-pb-collections.mjs. - src/lib/onboardingService.js: pure helpers (orderThemes, distributeThemesIntoDays, computeTopicsFingerprint, computeOnboardingProgress, buildOnboardingPlan) + generation + I/O. - db.js onboarding helpers use pb.filter() bindings (theme is free text). - LLM tool + Zod schema + registry + simulation stub. Frontend: - src/pages/OnboardingTrack.jsx (day list, per-theme overview, completion banner, progress ring/day bar). - Dashboard "New here?" card CTA + X/5-days progress chip (hidden when the KB has no themes). Docs: data-model, generation-spec (§D), frontend-spec updated. Verified: 22 new unit tests (npm test 134/134), eslint clean on changed files, npm run build OK, PocketBase v0.30.4 boot applies the migration (collections + unique indexes + authed rules confirmed), and a backend contract check (upsert idempotency, unique-index guard, special-char theme filtering). Closes #30 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4.8 KiB
Frontend spec
A React 19 SPA built with Vite, routed by React Router 7. Entry: src/main.jsx →
src/App.jsx. Global state lives in src/store/AppContext.jsx.
Routing & access control (src/App.jsx)
| Route | Screen | Access |
|---|---|---|
/login |
Login.jsx |
public |
/onboarding |
Onboarding.jsx |
logged-in, not yet enrolled (enrollment page) |
/ |
Dashboard.jsx |
enrolled user |
/onboarding-track |
OnboardingTrack.jsx |
any logged-in user, any enrollment (skipEnrollmentGate) |
/learn |
Leren.jsx |
enrolled user |
/test |
Testen.jsx |
enrolled user |
/leaderboard |
Leaderboard.jsx |
enrolled user |
/admin/* |
Admin/index.jsx |
role === 'admin' |
ProtectedRoute:
- redirects to
/loginif not authenticated; - redirects to
/onboardingifenrollment_status !== 'active'— except admins heading to the admin panel, and routes passingskipEnrollmentGate(the onboarding track), which are exempt; - enforces
requireAdminfor/admin.
/onboarding(enrollment) and/onboarding-track(the 5-day theme intro) are distinct. The track is decoupled from enrollment on purpose so it also works as a refresher for existing staff.
Navigation chrome (top bar + mobile bottom nav) is rendered by ProtectedRoute.
ChatLauncher (R42) is mounted globally.
Auth & global state (AppContext.jsx)
- Loads
team_memberson mount; auto-creates anAdmin(PIN0000) if the table is empty. - PIN login resolves a member and stores the id in
sessionStorage.respellion_session. state.currentUserholds the member;state.weekNumberis the user's absolute curriculum week, derived fromcurriculum_started_atviagetPersonalWeekNumber(0 until enrolled).enrollCurrentUser()stampscurriculum_started_at = now, setsenrollment_status = 'active', and updates state.
Onboarding (Onboarding.jsx)
A blocking first-login screen. One CTA — "Start my journey" — calls
enrollCurrentUser() and routes to /. Week 1 begins immediately. Users already
enrolled are redirected to /. See docs/curriculum-spec.md.
Employee screens
- Dashboard — current cycle/week, assigned topic, cycle progress ring, quick
links to Learn and Test, mini leaderboard, recent activity. The dismissible
"New here?" explainer card also carries the onboarding-track CTA (a progress
chip
X/5 days+ a Start/Continue/Review button linking to/onboarding-track), shown only when the KB has themes to introduce. - Onboarding Track (
/onboarding-track) — a self-paced, breadth-first tour of every theme, grouped into ≤5 day cards (OnboardingTrack.jsx). Opening a theme lazily generates a short overview (what it is / why it matters for daily & weekly work / key points / topics) and offers "Mark as done"; a progress ring + day bar track completion, and a completion banner shows when every theme is done. Available to any logged-in user regardless of enrollment; completion is stored per theme inonboarding_completions. Seedocs/generation-spec.md §D. - Learning Station (
/learn) — the week's required topic + the rest of the knowledge library; opening a topic shows the micro-learning selector (src/components/micro_learning/). Completing ≥1 micro-learning marks the week done. - Test (
/test) — 5-question quiz with a 5-minute timer, per-question feedback, and a results/review screen. Sets thequiz:activeflag to hide R42. - Leaderboard (
/leaderboard) — podium + ranked list + badges (seedocs/gamification-spec.md).
Labels show Cycle X · Week Y of 26, where Y/X come from getCurriculumWeek /
getCurriculumCycle applied to state.weekNumber.
Admin panel (Admin/index.jsx)
Tabbed: Sources (upload + extraction), Content (review/refine generated content), Quizzes, Curriculum (generate/preview/activate a schedule), Graph (D3 knowledge graph + R42 suggestions queue), Team (manage members), Settings (per-tier model overrides, simulation toggle, smoke-test reset).
Design system
- CSS variables in
src/index.css: colors (--color-bg,--color-paper,--color-teal,--color-accent), radii (--r-sm,--r-lg,--r-org). - Tailwind v4 utilities map to those variables (
bg-teal,text-fg-muted,border-bg-warm, …). Avoid raw hex. stylesheet.css(repo root) is the authoritative visual reference — frozen.- Reuse
src/components/ui/primitives:Card,Button,Tag,Input. - Framer Motion for entry animations; mobile-first (target 375px).
Build (vite.config.js)
- Injects
__BUILD_SHA__/__BUILD_TIME__(shown byBuildStamp). - Dev server proxies
/api/anthropicto Anthropic and injectsANTHROPIC_API_KEY. - Source maps on; production build outputs to
dist/.