feat(platform): in-app help & learning center with eLearning content (#1922)#1938
feat(platform): in-app help & learning center with eLearning content (#1922)#1938larryro wants to merge 1 commit into
Conversation
…1922) Add an in-app Help & learning center at /dashboard/help covering the three pillars from the issue: LLM fundamentals, platform how-tos, and the opportunities & risks of AI (responsible-use guidance). - New route app/routes/dashboard/help.tsx: a localized master-detail learning portal (curriculum sidebar + lesson content), deep-linkable via ?lesson=. - app/features/help/content.ts: curriculum structure (categories, lessons, reading time, optional self-hosted video src); all copy resolved from i18n. - LessonVideo: self-hosted <video> with a 'coming soon' placeholder. External embeds are intentionally unsupported — the deployment CSP pins media-src and frame-src to 'self' for offline/self-hosted installs. - user-button: the account menu now links to the in-app learning center alongside the existing external feedback link. - Full en/de/fr translations + metadata; dynamic key prefixes allowlisted. - Tests: curriculum↔i18n wiring, LessonVideo (both branches + axe), user-button menu, and an e2e render-smoke for the route.
|
Warning Review limit reached
More reviews will be available in 50 minutes. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (13)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
larryro
left a comment
There was a problem hiding this comment.
Desk review — feat(platform): in-app help & learning center (#1922)
Verdict: READY TO MERGE. Clean, well-scoped, fully localized implementation that genuinely resolves the issue. CI is green and the project's own tests pass.
What I verified
- CI: all required checks pass (
gh pr checks— Type check, Lint, Format, Knip, Unit, UI, Storybook, Build platform, all 16 Playwright platform shards, Smoke test, Scan platform, etc.). No red, no pending. - Tests run locally (bun + vitest):
bunx vitest --run --config vitest.ui.config.ts app/features/help app/components/user-button→ 21 passed- i18n
messagessuite → 40 passed (orphan-key + en/de/fr parity) content.test.ts→ 6 passed
- i18n parity: all 49
help.*/metadata.helpkeys present and non-empty in en, de, fr — no missing/extra. - Routing:
/dashboard/helpis org-independent and auth-guarded via the/dashboardparentbeforeLoad(same pattern aschangelog).?lesson=resolves valid → that lesson, invalid/missing → first lesson.routeTree.gen.tsregenerated correctly. - CSP/video posture:
LessonVideoself-hosts<video>+ same-origin WebVTT and falls back to an accessible "coming soon" placeholder — consistent with themedia-src 'self'air-gapped posture described in the PR. - Content: all three issue pillars are substantively delivered (not stubs) — LLM fundamentals (what/how/limitations incl. hallucinations), platform how-tos (getting started, agents, knowledge base, automations), and opportunities & risks + responsible-use best practices.
Non-blocking nits (optional follow-ups, do not block merge)
- Dead i18n copy.
help.lessons.<id>.summary(×10) andhelp.categories.<id>.description(×3) are authored in all three languages and asserted truthy bycontent.test.ts, but are never rendered byhelp.tsx(onlytitle/body/contact.descriptionare used). Either surface them (e.g. nav/lesson preview text) or drop them to avoid orphan copy. They escape the orphan-key scanner because the wholehelp.lessons/help.categoriesprefixes are allowlisted inkeys-dynamic.txt. - Latent
.vttassumption.lesson-video.tsxalways emits<track src={${videoSrc}.vtt} default>when avideoSrcis set; whoever adds a clip must drop the sibling.vttalongside it or captions silently 404. Currently inert (no lesson setsvideoSrc). - Test depth. The
?lesson=valid/invalid/missing resolution and theHelpNavdeep-link interaction are covered only by thepage-loadse2e smoke (heading visible), consistent with how sibling routes are tested. A smallhelp.test.tsxexercising the three param branches would harden it, but this matches repo convention and is not required.
I reviewed the dormant onNavigate prop on the new help menu item — the sole <UserButton> render passes no onNavigate, so it's a no-op everywhere today (and the in-file "What's New" link already navigates without it). Not a defect.
Summary
Resolves #1922 — adds an in-app Help & learning center at
/dashboard/help, the end-user learning surface the issue asked for. It covers the three pillars from the issue:The account menu (
user-button) now links to this in-app center alongside the existing external feedback link, replacing the old "help points only totale.dev/contact" state.Video hosting decision
The platform CSP pins
media-srcandframe-srcto'self'for offline / self-hosted deployments, so external embeds (YouTube/Vimeo) are intentionally unsupported.LessonVideoplays self-hosted clips via a native<video>element (with same-origin WebVTT captions) and falls back to an accessible "coming soon" placeholder until clips are produced. This keeps the feature consistent with the air-gapped posture.What's included
app/routes/dashboard/help.tsx— localized master-detail learning portal (curriculum sidebar + lesson content), deep-linkable via?lesson=.app/features/help/content.ts— curriculum structure; all copy resolved from the newhelpi18n namespace.app/features/help/components/lesson-video.tsx— self-hosted video / placeholder.metadata.help; dynamic key prefixes allowlisted inkeys-dynamic.txt.user-buttonaccount-menu entry → in-app learning center.Tests
content.test.ts— every curriculum id resolves to a real localized message (guards the dynamic-key wiring).lesson-video.test.tsx— placeholder & self-hosted branches + axe a11y audit.user-button.test.tsx— menu now exposes the learning-center item.page-loads.spec.ts— e2e render-smoke for/dashboard/help.Locally green:
tsc --noEmit,oxlint(changed files), i18n parity/usage (messages.test.ts), and the UI test suite above.Follow-ups
videoSrc) can be dropped in per lesson once produced.docs/could cross-link to this center.