Skip to content

feat(learning): import local roadmap packs into the catalogue - #93

Merged
OthmaneZ05 merged 1 commit into
mainfrom
feat/local-roadmap-import
Aug 22, 2026
Merged

feat(learning): import local roadmap packs into the catalogue#93
OthmaneZ05 merged 1 commit into
mainfrom
feat/local-roadmap-import

Conversation

@OthmaneZ05

Copy link
Copy Markdown
Collaborator

Summary of Changes

Roadmaps no longer have to live in the repo's roadmaps/ directory. This PR adds local import of roadmap packs:

  • Catalogue merge: the learning catalogue now scans two directories on every request — the shipped roadmaps/ (source builtin) and ~/.torollo/roadmaps/ (source imported). Dropping a valid file in the user folder makes it appear on refresh, no restart.
  • Import endpoint: POST /api/learning/roadmaps/import accepts a raw .json roadmap or a .zip archive of them (magic-byte detection, adm-zip, entry-count/size caps). Every file is Ajv-validated before anything is written and the response is a per-file report (imported / rejected with exact field-level errors / ignored), so a typo in a hand-written roadmap is an actionable message, not a silent failure.
  • No shadowing: progression is keyed on roadmap id, so an import colliding with a shipped (id, language) is refused with a clear message — both at import time and at scan time for hand-dropped files. Installed files are named <id>.<language>.json, so re-importing a fixed pack updates in place (updated in the report).
  • Frontend: an Import roadmaps button on the Learning page with a report modal, an "Imported (EN)" badge on catalogue cards, and imported roadmaps bypass the UI-language filter (an EN-only pack stays visible in a FR UI — you installed it on purpose). i18n EN/FR.
  • Docs: new docs/local-roadmaps.md, plus updates to docs/learning-api.md, docs/roadmap-format.md and the README.

Roadmaps remain pure data — importing never executes anything from the file.

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: 470 jest tests passing (incl. 12 new import-service tests with real zip archives, 6 controller tests, merged-catalogue service tests). Frontend: 310 vitest tests passing (incl. language-filter bypass and import-button tests). Both builds and lints clean.

Manual Verification

End-to-end against real Docker, on an isolated backend (HOME scratch dir, compiled dist/):

  • Imported a .zip containing a valid roadmap, an invalid one and a README → 200 with 1 imported, 1 rejected with field-level errors, 1 ignored; catalogue then listed the 6 shipped roadmaps in curated order plus the imported entry marked imported.
  • Played the imported roadmap end to end: fail-first validation on both steps, created the real ubuntu + postgres containers, both steps passed, replay stable, progression 2/2 persisted, completion reached.
  • Collision with shipped resilient-three-tier422 with the explanatory refusal.
  • Real UI (Playwright): import button + report modal, "Imported" badge, re-import shows updated, briefing page of the imported roadmap works, and the EN-only imported roadmap stays visible with the UI switched to French.
  • Broken upload with a wrong Content-Type gets an explicit 400 telling the client to use application/octet-stream.

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 August 18, 2026 03:44
@OthmaneZ05
OthmaneZ05 merged commit 20ed58a into main Aug 22, 2026
4 checks passed
@OthmaneZ05
OthmaneZ05 deleted the feat/local-roadmap-import branch August 22, 2026 03:12
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.

1 participant