A learning platform used by 1.8M learners
Led front-end development and rebuilt a legacy platform the company had written off as unprofitable. It became the company's main income stream.
At a glance
- Role
- Lead Front-End Developer / Team Lead for the whole engagement, plus technical interviews and the client relationship
- Engagement
- Employee of Avallain, delivering for an education publisher
- Timeframe
- Feb 2019 – Sep 2022
- Team
- The frontend team I led, with a Ruby on Rails backend team; 80% of Avallain's engineers worked on this project
- Stack
- Backbone → React · Redux / Redux-Saga · TypeScript · Ruby on Rails · PostgreSQL
- ◆1.8M learners on the platform
- ◆From written off as unprofitable to the company's main income stream
- ◆Monthly releases on a fixed schedule, with automated tests introduced and unused features removed
Context
The platform served learners for one of the world's largest education publishers. Publishing schedules do not move: a release tied to a school term is a date, not a target.
Internally the project was treated as unprofitable, and that judgement was becoming self-fulfilling. An old codebase nobody invests in gets slower to change, which confirms it was not worth investing in.
I proposed a long list of improvements and implemented a large share of them myself, rather than leaving them as a backlog nobody owned. By the time the project turned around, 80% of Avallain's engineers worked on it.
Constraints
- ›Schedule: monthly releases on a fixed date, tied to the publisher's calendar.
- ›Legacy: a Backbone front end that had accumulated features over years, many unused.
- ›Scale: 1.8M learners, so a regression reached all of them at once.
- ›Standing: a project the company had written off, which made investment hard to argue for.
Architecture
A Backbone front end, moved to React with Redux and Redux-Saga for state and side effects, in TypeScript, against a Ruby on Rails and PostgreSQL backend owned by a separate team. The publisher's team joined every Scrum call, so requirements arrived as a conversation rather than a handover.
Key decisions
| Decision | Why | Trade-off |
|---|---|---|
| Refactor the legacy system rather than work around it | The cost of changing the platform was the actual product problem; workarounds would have added to it. | A large refactor carries every inherited feature forward, including the ones nobody used. |
| Backbone → React, with Redux and Redux-Saga | A component model and explicit, testable state made the platform changeable again. | The migration had to run alongside fixed monthly releases, never instead of them. |
| Automated tests before speed | On a fixed release date, the release cannot also be the test. | Early releases carried test work alongside features. |
| Argue to cut features nobody used | I made the case to the product owner, PM and CTO that the platform was over-featured, and the unused features were removed. | It took standing I did not have at the start, so it came later than it should have. |
| Bring the client into every Scrum call | Requirements became a conversation instead of a handover. | A lead's time in client calls every sprint. |
Outcome
- ◆1.8M learners on the platform.
- ◆A project the company had written off as unprofitable became its main income stream, with 80% of Avallain's engineers working on it.
- ◆Monthly releases on a fixed schedule.
- ◆Automated tests introduced where there were none.
- ◆Unused features removed rather than maintained.
- ◆I also led the technical interviews for hiring onto the project.
What I'd do differently
- ›Inherit the approaches, not the code. The platform was over-featured from the start, and the refactor carried all of it forward: I spent effort making features maintainable before I had the standing to argue they should not exist.
- ›With the decision to make again, I would keep the parts and approaches worth keeping, write a clean codebase around them, and make the case for cutting scope in the first month, not a year in.