Skip to content

Persist onboarding learning times - #315

Merged
FleetAdmiralJakob merged 6 commits into
mainfrom
codex/day-65-personal-learning-times
Jul 25, 2026
Merged

Persist onboarding learning times#315
FleetAdmiralJakob merged 6 commits into
mainfrom
codex/day-65-personal-learning-times

Conversation

@FleetAdmiralJakob

@FleetAdmiralJakob FleetAdmiralJakob commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • derive one canonical userLearningTimes record per onboarding weekday from the selected start time and daily study duration
  • reject invalid and cross-midnight ranges in the onboarding UI and atomically on the backend, including when Settings already contains an authoritative row
  • preserve later Settings edits, close legacy recovery after authoritative changes, and make repeated onboarding synchronization idempotent
  • lazily recover only complete, unambiguous, valid legacy onboarding answers without treating those answers as a competing runtime source
  • show a brief completion message pointing learners to Settings → Lernzeiten
  • cover authenticated persistence, tenant isolation, Settings visibility, scheduling consumption, retries, validation, legacy recovery, rollback safety, and rendered correction/completion behavior

Root cause

Onboarding stored studyDays, learningTime, and dailySchoolTime only as historical userOnboardingAnswers. Settings and learning-plan generation read the separate userLearningTimes table, so completed onboarding could still leave the learner without scheduling availability.

User impact

Onboarding-created learning times now appear immediately in Settings and are consumed by learning-plan scheduling. Existing complete and unambiguous legacy answers are recovered safely, while invalid, incomplete, or ambiguous answers continue through the existing setup flow. Once onboarding, legacy recovery, or a Settings change establishes the authoritative schedule, old answers cannot resurrect times the learner later removes.

Validation

  • integrated current main (f89e8e7) and resolved the onboarding-flow conflict; final effective scope is nine focused files
  • pnpm install --frozen-lockfile with Node 24.18.0 and pnpm 11.15.1
  • pnpm check — Biome, ESLint, and TypeScript passing
  • pnpm test — 70 Vitest files / 352 tests and 21 Jest suites / 52 rendered UI tests passing, plus all auxiliary script tests
  • pnpm format:check
  • pnpm check:unused
  • git diff --check
  • independent Standards and Spec reviews — no actionable findings after final re-review
  • CodeRabbit hosted review through 3dc149d — no actionable comments; final hosted incremental review was rate-limited
  • CodeRabbit CLI review of the exact final delta (3dc149d…37e4fd7) — 0 issues
  • GitHub CI replacement run for 37e4fd7 — passed
  • all review threads resolved

Linear: DAY-65

Closes #64

UI evidence

day-65-onboarding-message.mp4

Note

I did not re-record it after the latest commits. The existing recording still shows the unchanged onboarding completion UI, while the subsequent changes were backend validation and recovery fixes. It is not evidence from the final commit 37e4fd7.

Summary by CodeRabbit

  • New Features
    • Onboarding now validates selected study days, start times, and durations, blocking schedules that would cross midnight.
    • Successfully derived learning times are saved during onboarding and backfilled for returning users when safe.
  • Bug Fixes
    • Improved onboarding loader completion behavior so navigation to the home screen occurs only when creation is complete.
    • Prevented invalid or ambiguous legacy onboarding data from generating incorrect learning times.
    • Learning time changes in settings now stay authoritative (no unintended resurrection).
  • Tests
    • Added extensive test coverage for validation, persistence, legacy recovery edge cases, and onboarding UI/error states.

@linear-code

linear-code Bot commented Jul 21, 2026

Copy link
Copy Markdown

DAY-65

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Onboarding learning-time data now uses shared validation and derivation logic, persists authenticated userLearningTimes records, supports safe legacy backfill, and validates midnight-crossing inputs in the onboarding UI. Creation-loader navigation now waits for synchronization completion.

Changes

Onboarding learning-time flow

Layer / File(s) Summary
Derive and validate learning-time windows
convex/learningTimeAvailability.ts, convex/learningTimeAvailability.test.ts
Defines shared duration options, input/output types, parsing, weekday sorting, midnight-crossing rejection, German error messages, and validation tests.
Persist and recover learning-time records
convex/users.ts, convex/users.test.ts
Creates records during onboarding, backfills eligible legacy answers during sync, preserves existing settings, reports inserted-record counts, and tests persistence, idempotency, rollback, ambiguity, and recovery behavior.
Track manual learning-time changes
convex/schema.ts, convex/learningTimesBackfill.ts, convex/learningTimes.ts
Adds version tracking for learning-time backfill and marks it handled when learning-time records are manually created, updated, or removed.
Validate onboarding and complete creation flow
src/features/auth/dayova-auth-flow.tsx, src/features/auth/login-screen.ui.test.tsx
Uses shared duration values, validates learning-time progression, supports an initial step, gates loader navigation on completion, and tests validation and completion states.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • Dayova/dayova-mvp#89: Both changes modify the learning-times backend and AI planning context integration.
  • Dayova/dayova-mvp#153: Both changes use the onboarding learning-time fields persisted by convex/users.ts.

Suggested reviewers: gamius00

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes persist onboarding times into userLearningTimes, sync with settings and learning plans, and add safe legacy recovery plus tests.
Out of Scope Changes check ✅ Passed The changes stay focused on onboarding learning-time persistence, recovery, UI flow, schema, and tests, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: onboarding learning times are now persisted as canonical records.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/day-65-personal-learning-times

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@FleetAdmiralJakob
FleetAdmiralJakob marked this pull request as ready for review July 25, 2026 16:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c23bb8e49

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread convex/users.ts Outdated
Comment thread convex/users.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
convex/users.ts (1)

230-273: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

backfillLegacyLearningTimes re-runs its full scan on every syncCurrentUser call until it succeeds — which never happens for permanently-ambiguous legacy data.

Since hasLearningTimes is the only gate, users whose legacy answers are incomplete/ambiguous (or who never had legacy answers) will pay the up-to-6-query scan on every single session sync indefinitely, since there's no persisted "already attempted, unrecoverable" marker.

Consider caching the outcome (e.g., a flag/timestamp on the user document, or a short-lived marker) so the scan is attempted at most once (or rate-limited) per user, rather than on every sync call.

Also applies to: 333-345

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@convex/users.ts` around lines 230 - 273, Update backfillLegacyLearningTimes
and its syncCurrentUser call path to persist an attempted/unrecoverable backfill
marker on the user, and check it before scanning. Set the marker when legacy
data is missing or ambiguous, while preserving successful insertion through
insertLearningTimesWhenAbsent; ensure permanently invalid users no longer repeat
the full query scan on every sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@convex/users.ts`:
- Around line 230-273: Update backfillLegacyLearningTimes and its
syncCurrentUser call path to persist an attempted/unrecoverable backfill marker
on the user, and check it before scanning. Set the marker when legacy data is
missing or ambiguous, while preserving successful insertion through
insertLearningTimesWhenAbsent; ensure permanently invalid users no longer repeat
the full query scan on every sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ea80d486-3518-43a7-acca-5266e91b282b

📥 Commits

Reviewing files that changed from the base of the PR and between f89e8e7 and 5c23bb8.

📒 Files selected for processing (6)
  • convex/learningTimeAvailability.test.ts
  • convex/learningTimeAvailability.ts
  • convex/users.test.ts
  • convex/users.ts
  • src/features/auth/dayova-auth-flow.tsx
  • src/features/auth/login-screen.ui.test.tsx

@FleetAdmiralJakob
FleetAdmiralJakob merged commit 6ca382c into main Jul 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add personal learn time

1 participant