Skip to content

Learning preferences editor

A dedicated "Learning preferences" tab in Settings lets a B2C learner edit the three answers the onboarding wizard collects (study stage, subjects, goal) after the wizard is done. The wizard itself tells users these are editable later.

How it works

The onboarding wizard writes study stage, subjects, and goal to the chat-memory profile the tutor personalizes from, then never reappears. This tab is the persistent editor for those values, so a learner who picked the wrong stage or whose subjects change next semester can correct them.

  • A dedicated Learning preferences tab in Settings, its own left-panel entry (LEARNING_TAB_ROLES), gated to B2C learners.
  • A flat inline form (RHF + Zod): study stage (single-select), subjects (multi-select, options scoped to the chosen stage), goal (single-select). Pre-filled from the user's saved answers. One Save preferences button saves in place with a success toast and no redirect.
  • Reuses the wizard's option data (EDUCATION_STAGES, ONBOARDING_GOALS, SUBJECTS_BY_STAGE) and the student.onboarding.step*.question labels, so the editor and wizard read identically.
  • A quiet hint ("You can change any of this later in your profile settings.") shows on every wizard step.

Data flow

  • Persisted at profile.preferences['onboarding'] on the kwiloai_memory profiles table, the same store the tutor and GET /student/home-context already read. Editing here keeps personalization and recommendations in sync.
  • GET /api/v1/onboarding/profile returns { education_stage, onboarding_subjects, onboarding_goal, completed_at } to pre-fill the form. (Previously only POST existed.)
  • Save reuses the existing idempotent POST /api/v1/onboarding/profile with submit: true.

Relationship to other surfaces

This tab is the sole persistent editor of these values:

Surface Relationship
Onboarding wizard First-run writer (the only entry that introduces the values)
Dashboard "pick subjects" / "jump in by subject" Reads subjects_prefilled from home-context; opens a chat with ?subject=. No write.
Chat composer subject chip Transient per-conversation context sent with each message. No write.
Learning preferences tab (this) The persistent editor

Out of scope: relaunching the wizard from settings, editing the transient per-conversation subject, and free-text "edit by chatting."

Where it lives

  • Settings "Learning preferences" tab, gated by LEARNING_TAB_ROLES (B2C)
  • GET / POST /api/v1/onboarding/profile
  • Local-dev: the editor needs the kwiloai-memory alembic chain applied (alembic -c alembic_kwilo_memory.ini upgrade head), otherwise the profiles table is missing and the endpoint 500s.