Skip to content

feat(learning): persist roadmap progression locally without an account#66

Merged
OthmaneZ05 merged 2 commits into
mainfrom
feat/learning-local-progress
Jul 16, 2026
Merged

feat(learning): persist roadmap progression locally without an account#66
OthmaneZ05 merged 2 commits into
mainfrom
feat/learning-local-progress

Conversation

@OthmaneZ05

Copy link
Copy Markdown
Collaborator

Summary of Changes

A roadmap is played across several sessions, but until now every player state died with the page: reloading meant starting from step 1. This PR persists roadmap progression locally — completed steps, validation attempts and revealed hints — with zero account and zero auth, so reopening a roadmap resumes exactly where the learner left off, even after fully restarting the app.

  • Backend store (~/.torollo/progress.json, next to projects.json): new ProgressService — versioned envelope (version: 1), one entry per (projectId, roadmapId), per-step data keyed by stable step ids (reordering/re-editing a roadmap file can't corrupt progress; translations share progress). Write-then-rename so a crash can't truncate the file. A corrupt or unknown-version store is moved aside as progress.json.corrupt, the app starts fresh, and the UI tells the user (one-shot storeRecovered flag) — never a crash, never silent.
  • Recording: POST /validate now records the attempt + latest verdict at the API layer (the engine stays stateless; a storage failure is logged and never blocks the verdict). Hint reveals are pushed by the player as absolute counts (fire-and-forget, self-healing). New endpoints: GET/PUT …/hints/DELETE under /api/learning/progress/:projectId/:roadmapId.
  • Player: opening a roadmap hydrates progress and resumes on the first incomplete step; restored steps show a ✓ marker in the step list (validator results are deliberately not replayed — they describe a past container state). New "Restart roadmap" action behind the same light two-click brake as the solution reveal. Recovery notice (amber, dismissible) when a corrupt store had to be reset. i18n en/fr.
  • Lifecycle: deleting a project purges its progress entries.

Contract documented in docs/learning-api.md (store format = the future migration contract).

Types of Changes

  • New feature / node type addition
  • Bug fix (non-breaking change resolving an issue)
  • Refactoring / structural cleanup
  • Documentation update

Verification & Testing

Automated Checks

  • Run npm run lint successfully with no errors
  • Run npm run build successfully with no compilation errors
  • Run npm test successfully (all tests pass)

Backend: 237 tests (20 new — ProgressService round-trips on real tmp files incl. corruption/unknown-version recovery and reset scoping; controller contract incl. "recording failure never blocks the verdict"). Frontend: 225 tests (12 new — hydration, first-incomplete-step resume, hint push, reset, recovery notice). Note: a few heavy pre-existing modal/canvas tests sit close to their 5s timeout and can flake under parallel load on a busy machine (seen on main files untouched by this PR, e.g. PostgresModal/NoSqlModal/CanvasPage); they pass consistently when the machine isn't saturated.

Manual Verification

Full kill & restart scenario against real Docker (Playwright + Chrome, example roadmap):

  1. Completed steps 1–2 through the UI (real web + db containers, seeded users table), revealed step 3's hint.
  2. Killed both dev servers, restarted → roadmap reopens on step 3, steps 1–2 carry ✓ markers, step 3's hint is still revealed; progress.json holds the exact attempts/verdicts.
  3. "Restart roadmap": first click arms the confirmation, second resets to step 1 and deletes only that roadmap's entry. FR labels verified.
  4. Hand-corrupted progress.json → app opens normally, amber notice shown once and dismissible, original file kept as progress.json.corrupt, next validation recreates a fresh store.
  5. Deleted the project → its progress entries purged with it.

Checklist

  • My code follows the repository's code style and lint standards
  • I have updated the documentation or instructions if necessary
  • All unit and integration tests are passing

@OthmaneZ05
OthmaneZ05 requested a review from Derssa as a code owner July 16, 2026 19:48
@OthmaneZ05
OthmaneZ05 merged commit e6aa379 into main Jul 16, 2026
3 checks passed
@OthmaneZ05
OthmaneZ05 deleted the feat/learning-local-progress branch July 16, 2026 19:59
OthmaneZ05 added a commit that referenced this pull request Jul 18, 2026
#66)

* feat(learning): persist roadmap progression locally without an account

* docs(learning): document the local progression store and its endpoints
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.

2 participants