Skip to end of banner
Go to start of banner

LearningBuilder Development Experience

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

If you're reading this page then you've either applied for a position on our product team, or you're thinking about. Welcome!

The purpose of this page is to provide detailed information about our technical stack and development environment. These details will, obviously, have a big impact on what day-to-day life on our team is like and it's only natural that you'd want to know about them in advance.

One note before we continue: software is an ever-changing field and some of these details may have changed by the time you read this!

Programming Languages / Platforms / Architectures

LearningBuilder is primarily written in ASP.NET MVC using C#, with a decent amount of custom JavaScript. We haven't adopted a SPA framework yet but are keeping tabs on both Angular and React as candidates when we go that route. 

It is a large, but reasonably well-organized, monolith consisting of a handful of core assemblies plus the web project. Our long-term vision is less monolithic and more a federation of independent services working together. We've begun exploring that vision by using a message bus (RabbitMQ) and an "integration hub" to handle integration and process coordination needs.

We use SASS to take some of the pain out of CSS. 

A lot of our development utilities are written in Ruby and we use Powershell for some production automation tasks.

Our primary database is SQL Server 2014+, and we Elasticsearch to power some of our publicly-accessible search features.

Developers run the full stack locally.

Data Access

All database schema changes are fully scripted (using a homegrown utility) and are source-controlled like everything else. We maintain a shared database snapshot in a known good state so that you're only ever one command-line tool away from restoring a local database with staged data.

Most of our features use an ORM called NHibernate to interact with the database. Queries are typically expressed using the NH LINQ provider, but when necessary we'll hand-roll a query to optimize performance.

We also work with stored procedures a decent amount; LearningBuilder is a very configurable product, and sprocs are often used as a way of injecting client-specific business logic into pre-defined "hooks" in the app.

Automated Testing

Automated testing is a big deal on our team. We switch between TDD, "test-first", and "test-after" workflows depending on the nature of the changes we're making. Regardless, the goals are always to:

  1. Prove our code does what we expect it does
  2. Document our intent to aid other programmers
  3. Prevent regressions and aid in issue triage

As of this writing we have 5,854 unit and integration tests and 195 automated UI tests. These tests can be executed via the command line, via the NUnit test runner, or within Visual Studio using R# or TestDriven.NET. 

We have invested heavily in a library of "data helpers" that assist with setting up test data, ensuring that it remains fairly easy to write new automated tests even as the product complexity continues to grow.

Source Control / CI

Currently we use SVN. We're hoping to switch to Git in 2018.

Our general pattern is that most tasks are performed in feature branches and then merged into trunk once they are stable and are code-reviewed. We maintain release branches so that critical changes can be merged across multiple lines of development if needed.

The entire test suite is automatically executed for each check-in to trunk, and we will often set up CI builds to monitor long-running feature or release branches as well.

Deployments

The process of preparing a release package is fully automated using a Ruby tool called Rake. Rake scripts will do a fresh checkout, compile the release package, run the tests, commit the package to source control, etc.

Deployments themselves are handled through Octopus Deploy and are approximately 75% automated. Our IT/Devops team manages the deployment process.

Principles and Values

We believe in the following:

  • "Go slow to go fast". We are interested in long-term stable velocity over time. We achieve that by paying attention to fundamentals, writing clean code, and sweating the details. 

  • Diversity of thought / consistency of output. We value different ideas and problem solving strategies, but the code shouldn't suffer from multiple-personality disorder. 

  • Product features should be thin wrappers of business logic around a rich application framework. This means we prefer reusable components and patterns over feature-specific "stuff". We invest in helpers, wrappers, utilities, etc to eliminate as much boilerplate and repetition as possible.

  • Automate all the things - ain't nobody got time to be doing repetetive tasks by hand!

  • Innovate deliberately. We all love shiny new stuff, but not every task is the right time to introduce brand new ways of doing things. But when it is the right time, then look for the evolutionary leaps and not the incremental shifts.

  • "It's better to build half a feature than a half-assed feature." (See #1)




  • No labels