Commercial engineering at scale
Enable 2.0: learning at scale
A greenfield learning platform combining ambitious browser-based authoring, standards-based course delivery, PDF generation, and independently designed distributed load testing.
- Role
- Software Developer → Architecture Owner
- Period
- 2013–2016
- Status
- Delivered production platform
- Focus
- C#, JavaScript, Microsoft SQL Server
Learning to engineer in a difficult legacy system
Virtual College was where I learned much of the discipline behind becoming a professional software engineer.
I initially worked on a large ASP.NET Web Forms learning platform whose foundations pre-dated my career. The team enabled static code analysis and spent months working through roughly 40,000 findings while continuing to develop the product, often on development machines that made every feedback cycle slow. It was not glamorous work, but it taught me how to improve a consequential system incrementally, understand unfamiliar code, and value maintainability rather than treating greenfield development as the only interesting engineering problem.
That experience informed Enable 2.0, a greenfield replacement built by a team of around five developers over several years. The product as a whole was emphatically a team achievement. Within it, I developed several of its more technically unusual capabilities and progressed from Software Developer to Architecture Owner.
Rich browser tooling before modern frameworks became the default
Enable 2.0 was built when sophisticated web application behaviour still required much more bespoke JavaScript engineering. We used a custom JavaScript application layer with Knockout.js to create interfaces that felt like desktop authoring tools rather than conventional forms.
The compatibility target pulled in two opposing directions: management wanted a polished, touch-friendly experience on then-current tablets that felt close to a native iOS application, while the same product still had to work in Internet Explorer 8. Every ambitious interaction therefore had to account for an old browser model as well as touch input, smaller screens, and contemporary expectations. Delivering the experience across both was a significant part of the engineering rather than a final compatibility pass.
My work included dynamic reporting interfaces and visual editors for learning modules and certificates. The certificate editor was an especially interesting cross-runtime problem: administrators designed a certificate visually in the browser, but the finished document had to be generated on the server with PDFsharp. I designed the shared representation and translation path for positioning, styling, images, and dynamic learner fields so that the exported PDF matched the browser-authored design.
I also used MigraDoc and PDFsharp extensively for downloadable reports. These features required more than producing a document: users needed flexible reporting controls, predictable pagination, and output that remained useful outside the web application.
A reusable SQL pattern for complex interfaces
Enable contained many data-heavy interfaces that had to be searchable, filterable, sortable, and paged in different combinations. I spent weeks developing a consistent, reusable T-SQL pattern for those screens rather than accepting inefficient or unpredictable database access as the cost of a flexible UI.
The wider application used Entity Framework, but these were cases where deliberately written SQL gave us the control and performance the product needed on Microsoft SQL Server. The approach became part of my engineering toolkit: I still apply the same principles when an otherwise useful ORM—now usually Entity Framework Core—cannot produce an adequate query for a demanding read path.
Treating SCORM as a platform capability
I developed a substantial implementation of the SCORM 1.2 specification rather than a thin file-upload integration. It covered package and manifest import, content and resource handling, the runtime API, learner state, objectives, interactions, prerequisites, progress, and completion data.
The aim was to make third-party learning content behave consistently inside the wider platform while preserving the detailed learner records needed by customers. The implementation was supported by dedicated automated tests because interoperability code becomes expensive very quickly when standards are interpreted inconsistently.
Early real-time product features
I introduced SignalR to Enable for its built-in chat and notification systems while the technology was still a relatively new part of the .NET web stack. It let the platform deliver changes immediately rather than making users repeatedly poll the server.
I later used the same technology in a less conventional way. For the performance-test system, SignalR became the remoting layer between a central controller and load-generating agents running across multiple machines. That reuse was architectural rather than incidental: the same bidirectional messaging model that supported live browser features was also a good fit for coordinating distributed test infrastructure.
Building a distributed performance laboratory
The platform needed to support more than 10,000 simultaneous users on a constrained on-premises server estate. A normal load test running from one machine could saturate that machine or its network connection first, creating a convincing graph without accurately measuring the application.
On my own initiative, I designed and built a distributed performance system around a controller and any number of connected agents. The controller divided realistic use-case instances between available nodes, assigned test users, coordinated login and execution, and collected the results centrally. Each simulated user maintained an independent authenticated session, including cookies and anti-forgery state, and could exercise navigation, Ajax requests, static resources, and live SignalR connections.
The use cases were based on observed production behaviour rather than a single repeated endpoint. They could vary start times, repeat patterns, user roles, and application journeys, producing load that more closely resembled thousands of people using the system concurrently. Test runs stored request timings, node details, events, and errors for later analysis instead of reducing the outcome to one headline throughput number.
Using evidence to improve the platform
The distributed tooling made performance work repeatable and helped distinguish application bottlenecks from limitations in the test generator. I used its measurements alongside profiling to find expensive paths, change implementations, and verify the result under representative load.
Across that programme, average page response under the full simulated load fell from roughly five seconds to below 100 milliseconds. The important result was not just the final number: the team gained a way to reproduce demanding traffic, identify where time was being spent, and check that an optimisation survived realistic concurrency.
The result
Enable 2.0 was a broad product created through sustained team effort. My contribution spanned user-facing JavaScript tools, server-side document generation, standards-based learning integration, real-time communication, architecture, and performance engineering.
The work also traces an important stage in my development: from learning how to improve a difficult inherited system to designing platform capabilities and independently creating the infrastructure needed to prove that a major replacement would perform at scale.
Why I include this work
- Progression from hands-on development to architectural responsibility on a large product.
- Honest collaboration and ownership boundaries within a long-running five-person engineering team.
- Rich JavaScript application engineering in the pre-React/Vue era.
- App-like tablet experiences delivered while retaining Internet Explorer 8 support.
- Deep Microsoft SQL Server and T-SQL work behind reusable searchable, filterable, sortable, and paged interfaces.
- Translating a browser-based WYSIWYG design into reliable server-generated PDF output.
- Deep implementation of the SCORM 1.2 learning-content standard.
- Early adoption of SignalR for live chat and notifications.
- Reusing SignalR as a practical remoting stack for distributed test agents.
- Independent initiative in designing realistic, multi-node performance infrastructure.
- Evidence-led optimisation against a target of more than 10,000 concurrent users.