0001. Monorepo with vendored packages
Generated from docs/decisions/0001-monorepo-with-vendored-packages.md
- Status: Accepted (2026-10-08)
- Date: 2026-10-08
Context and problem statement
Section titled “Context and problem statement”ulams started as three repositories (Laravel API, React admin, React front) glued together by about
57 published packages: 50 escolalms/* composer packages and 7 @escolalms/* npm libraries. Every
change to domain code meant a release in another repository, version bumps and lockfile churn, and
the roadmap (Living Course, Course Builder, learner insights) needs coordinated changes across the API
and both frontends.
Decision
Section titled “Decision”- One git repository with three applications:
api/,admin/,front/(plusdocs/and root tooling files). The history of the three original repositories is preserved, rewritten into their folders withgit filter-repo. - All 50 PHP packages live as source in
api/packages/<name>(copied from the exact locked commits).api/composer.jsonhas no dependency on them: namespaces are autoloaded via PSR-4 and service providers are registered explicitly inconfig/app.php. Their third-party requirements are merged into the rootcomposer.json. - The JS libraries live as source:
components,sdk,ts-modelsandscorm-playerinfront/src/lib,gift-pegjsandmarkdown-editorinadmin/src/lib, imported through the@ulams/*alias. Admin reusests-modelsandscorm-playerfromfront/src/lib(single copy). - Each vendored package keeps a provenance note (upstream repository, version, commit).
Consequences
Section titled “Consequences”- Good: one pull request can change domain code, API and UI together; no package releases.
- Good: local development and CI build everything from one checkout.
- Bad: no more independent package versioning;
/api/core/packagesreadsapi/packages/versions.json. - Bad: package test fixtures make the repository larger (~81 MB in
api/packages). - Follow-up: per-package licence obligations still apply (see the licence audit, Phase 0.1).