Onboarding-track: 5-daagse thema-introductie vanuit de "New here?"-kaart (#30) #31

Merged
rve merged 2 commits from feat/onboarding-track into main 2026-07-13 07:20:01 +00:00
Owner

Closes #30

Wat & waarom

Een zelf-gepacete 5-daagse onboarding-track die een nieuwe medewerker in de breedte (niet de diepte) kennis laat maken met alle KB-thema's, zodat ze de dagelijkse/wekelijkse werkprocessen van Respellion begrijpen. Aangeboden als CTA in de bestaande "New here?"-kaart op het Dashboard; altijd beschikbaar, los van enrollment.

Ontwerp

  • Thema = trackbare eenheid; "dag" = presentatie-groepering (berekend bij het lezen) → herindeling verliest nooit voortgang. Voltooiing per thema in onboarding_completions.
  • Lazy, gecachte, lichte AI-content: fast-tier emit_onboarding_overview per thema (wat het is / waarom het ertoe doet voor dagelijks/wekelijks werk / kernpunten / topics), gecached in onboarding_overviews op thema + topics_fingerprint (hergeneratie bij gewijzigde topic-set).
  • Route /onboarding-track via de bestaande skipEnrollmentGate-prop, ontkoppeld van het 26-weken-curriculum (los van /onboarding, de enrollment-pagina).
  • Twee nieuwe collections met authenticated-only rules + unieke indexes; TEXT team_member_id (post-#18/#27-conventie).

Verificatie

  • 22 nieuwe unit-tests voor de pure helpers → npm test 134/134.
  • ESLint schoon op alle gewijzigde bestanden; npm run build OK.
  • PocketBase v0.30.4 boot past migratie 1781200000 toe — beide collections aanwezig met de juiste unieke indexes en @request.auth.id != ""-rules (geverifieerd via de API).
  • Backend-contract: upsert-idempotentie, unieke-index-guard (dubbele create → 400), en veilige filtering op thema's met speciale tekens (&, spaties) via pb.filter().

Reviewpunten

  • .github/workflows/ niet aangeraakt. De bekende falende caddy validate-stap (#26/PR #28/#29) staat los hiervan.
  • Content-taal is Engels, passend bij de "New here?"-kaart.
  • Geen leaderboard-punten en geen afsluitende quiz (bewuste productkeuze).

Handmatige E2E (na deploy)

Dashboard → "New here?" → CTA 0/5 days/onboarding-track → thema openen (overview genereert, "Mark as done") → chip loopt op → alles klaar → afrondingsscherm + "Onboarding complete". Optioneel localStorage['admin:use_simulation']=true om de AI-call te stubben.

🤖 Generated with Claude Code

Closes #30 ## Wat & waarom Een zelf-gepacete **5-daagse onboarding-track** die een nieuwe medewerker in de breedte (niet de diepte) kennis laat maken met **alle** KB-thema's, zodat ze de dagelijkse/wekelijkse werkprocessen van Respellion begrijpen. Aangeboden als CTA in de bestaande **"New here?"**-kaart op het Dashboard; altijd beschikbaar, los van enrollment. ## Ontwerp - **Thema = trackbare eenheid; "dag" = presentatie-groepering** (berekend bij het lezen) → herindeling verliest nooit voortgang. Voltooiing per thema in `onboarding_completions`. - **Lazy, gecachte, lichte AI-content**: fast-tier `emit_onboarding_overview` per thema (wat het is / waarom het ertoe doet voor dagelijks/wekelijks werk / kernpunten / topics), gecached in `onboarding_overviews` op thema + `topics_fingerprint` (hergeneratie bij gewijzigde topic-set). - **Route `/onboarding-track`** via de bestaande `skipEnrollmentGate`-prop, ontkoppeld van het 26-weken-curriculum (los van `/onboarding`, de enrollment-pagina). - Twee nieuwe collections met authenticated-only rules + unieke indexes; TEXT `team_member_id` (post-#18/#27-conventie). ## Verificatie - **22 nieuwe unit-tests** voor de pure helpers → `npm test` **134/134**. - **ESLint** schoon op alle gewijzigde bestanden; **`npm run build`** OK. - **PocketBase v0.30.4 boot** past migratie `1781200000` toe — beide collections aanwezig met de juiste **unieke indexes** en **`@request.auth.id != ""`-rules** (geverifieerd via de API). - **Backend-contract**: upsert-idempotentie, unieke-index-guard (dubbele create → 400), en veilige filtering op thema's met speciale tekens (`&`, spaties) via `pb.filter()`. ## Reviewpunten - `.github/workflows/` niet aangeraakt. De bekende falende `caddy validate`-stap (#26/PR #28/#29) staat los hiervan. - Content-taal is Engels, passend bij de "New here?"-kaart. - Geen leaderboard-punten en geen afsluitende quiz (bewuste productkeuze). ## Handmatige E2E (na deploy) Dashboard → "New here?" → CTA `0/5 days` → `/onboarding-track` → thema openen (overview genereert, "Mark as done") → chip loopt op → alles klaar → afrondingsscherm + "Onboarding complete". Optioneel `localStorage['admin:use_simulation']=true` om de AI-call te stubben. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
rve added 1 commit 2026-07-13 07:09:26 +00:00
feat: 5-day theme-level onboarding track from the "New here?" card (#30)
Some checks failed
On Pull Request to Main / test (pull_request) Failing after 24s
On Pull Request to Main / publish (pull_request) Has been skipped
On Pull Request to Main / deploy-dev (pull_request) Has been skipped
5214c9db3b
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>
rve added 1 commit 2026-07-13 07:13:20 +00:00
ci: validate the production Caddyfile inside the built image (#26)
All checks were successful
On Pull Request to Main / test (pull_request) Successful in 41s
On Pull Request to Main / publish (pull_request) Successful in 1m10s
On Pull Request to Main / deploy-dev (pull_request) Successful in 3m15s
b1330ebe3e
The caddy-validate step added for #26 (and merged to main via #29) used a
`-v "$PWD":/workspace` bind mount, which does not propagate to the sibling
Docker daemon in the Gitea act runner — the container saw an empty dir and
every PR failed with "open Caddyfile: no such file or directory".

Validate instead inside the freshly built image, where the production
Caddyfile lives at /etc/caddy/Caddyfile: no bind mount, and it checks the
exact file that ships. Caddyfile.test keeps being covered by the homepage
smoke test (its container must serve 200).

Closes #26

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

Pipeline groen (run #101). test · publish · deploy-dev — PLAY RECAP failed=0, beide containers Up, proxy-health 200.

Twee dingen om te weten bij review:

  1. CI-fix meegenomen (Closes #26). De eerste run (#100) faalde op de caddy validate-stap — niet door deze feature, maar door de bind-mount-bug uit #26 die via de merge van #29 op main terechtkwam (open Caddyfile: no such file or directory, mount propageert niet naar de sibling Docker-daemon in de Gitea-runner). Die stap blokkeerde élke PR naar main. Opgelost door de productie-Caddyfile te valideren binnen het gebouwde image (/etc/caddy/Caddyfile), zonder mount. Dit maakt PR #28 overbodig — die kan dicht.
  2. Migratie toegepast op Labs. PocketBase crash-loopt bij een migratiefout (zie #18); de container is healthy en de deploy-health-gate is groen, dus 1781200000 is schoon toegepast. Lokaal bovendien geverifieerd: beide collections aanwezig met unieke indexes + @request.auth.id != ""-rules, plus een backend-contracttest (upsert-idempotentie, unieke-index-guard, filtering op thema's met speciale tekens).

Handmatige E2E (na merge/als je nu op Labs kijkt): Dashboard → "New here?" → CTA 0/5 days/onboarding-track → thema openen → "Mark as done" → chip loopt op → afrondingsscherm. Zet eventueel localStorage['admin:use_simulation']=true om de AI-call te stubben.

**Pipeline groen (run #101).** test ✅ · publish ✅ · deploy-dev ✅ — PLAY RECAP `failed=0`, beide containers Up, proxy-health 200. Twee dingen om te weten bij review: 1. **CI-fix meegenomen (Closes #26).** De eerste run (#100) faalde op de `caddy validate`-stap — niet door deze feature, maar door de bind-mount-bug uit #26 die via de merge van #29 op `main` terechtkwam (`open Caddyfile: no such file or directory`, mount propageert niet naar de sibling Docker-daemon in de Gitea-runner). Die stap blokkeerde élke PR naar main. Opgelost door de productie-Caddyfile te valideren *binnen* het gebouwde image (`/etc/caddy/Caddyfile`), zonder mount. Dit maakt PR #28 overbodig — die kan dicht. 2. **Migratie toegepast op Labs.** PocketBase crash-loopt bij een migratiefout (zie #18); de container is healthy en de deploy-health-gate is groen, dus `1781200000` is schoon toegepast. Lokaal bovendien geverifieerd: beide collections aanwezig met unieke indexes + `@request.auth.id != ""`-rules, plus een backend-contracttest (upsert-idempotentie, unieke-index-guard, filtering op thema's met speciale tekens). Handmatige E2E (na merge/als je nu op Labs kijkt): Dashboard → "New here?" → CTA `0/5 days` → `/onboarding-track` → thema openen → "Mark as done" → chip loopt op → afrondingsscherm. Zet eventueel `localStorage['admin:use_simulation']=true` om de AI-call te stubben.
rve merged commit b1d3686d35 into main 2026-07-13 07:20:01 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rve/learning-platform#31