/projects/dietbox

← All projects

Dietbox Webapp

None of today’s APIs existed. All of it started in here.

Senior Software Engineer, then Head of Technology · 2020–2024

C#ASP.NET MVCEntity FrameworkSQL ServerAzure App ServiceKendo UIAzure DevOps
WebsitePrivate
Dietbox Webapp screenshot

Overview

When I arrived, this was the product. The nutritionist’s tool, the patient’s, subscriptions, food data, sign-in — one codebase, one release, one schedule. None of the services that run beside it now existed yet. Over four years I took the logic out of it a piece at a time and stood each piece up as an API of its own, leaving the monolith serving whatever had not moved. It is still the product’s largest codebase.

What I did

Principal architect for four years. I ran the extraction — what came out of the monolith, in what order, and what shape it took on the other side — set the platform’s patterns, and configured the Azure estate, including for services other people wrote. Later the whole technology organization reported to me.

  • The build and release pipeline in Azure DevOps, shipping the core project together with its satellites and its gulp-built, Kendo UI front end.
  • Production availability and incident response.

The product’s largest codebase was a team effort — about a sixth of that repository’s commits are mine.

The problem

The nutritionist lives in the tool all day; the patient opens it to read a meal plan. Same product, opposite expectations. In 2020 a .NET Framework monolith carried both on Windows App Service — and sign-in, subscriptions and the food data with them — shipping once a day, at night, because that was the only window that felt safe. Anything the product needed to do differently had to be done inside it.

By the numbers

The commit counts come from the repository. The rest is my own record of the period.

~600commits in the monolithmine, of ~3.9k total
4 yearsin the same codebase2020 to 2024

Architecture

The core project, its data, the scheduled job beside it, and the Azure app it deploys onto.

  1. Web applicationThe core project and its satellites — catalogs, enums, shared infrastructure, resources and reports — behind a gulp-built front end using Kendo UI.
  2. Data layerEntity Framework over SQL Server, the store the monolith reads and writes through.
  3. Background jobsA webjob project for scheduled work — a single daily job — sitting in the repository but outside the solution the release builds, and published on its own.
  4. Azure App ServiceA Windows app with a staging slot: the release deploys the built artifact to the slot, then swaps the slot into production.

What it does

  • Diet planning for the practitioner, and the same plan in the patient’s own app.
  • Two sign-up journeys over one identity system — a practitioner subscribing, and a patient invited by the one treating them.
  • Live updates pushed to open clients without a refresh.
  • Subscriptions and recurring billing.

Engineering decisions

  • One core, many satellites

    The core project doesn't carry catalogs, enums, shared infrastructure, resources and reports itself — each lives in its own satellite project. A change to reference data doesn't touch the same project as a change to the request path.

  • The release builds a target, not the solution

    The release pipeline restores the solution but builds a single target — the site project — and archives only what that target publishes. The webjob project sitting beside it in the repository is not in the solution at all: it still targets 4.7.2 where the site targets 4.8, carries its own daily-schedule publish settings, and has not been touched since 2021. Naming a target rather than a solution is what keeps a project in that state from riding into a release nobody meant to include it in.

  • Release by slot swap, not by overwrite

    The pipeline builds once and deploys that one artifact to the app’s staging slot; production changes by swapping the slot in, not by writing over the site while it is serving. What goes live is a build that was already running before it took traffic, and the way back is the same swap in the other direction. That is what a deploy has to be before it can happen in daylight rather than at night.

  • A monolith you strangle, not rewrite

    The monolith was not ported and not rewritten. Logic came out of it a piece at a time — sign-in, payments, food data, the back office, notifications, realtime — and each piece became an API running beside it, while the monolith kept serving whatever had not moved yet. A rewrite would have competed for the same hours as the features shipping everywhere else, and the product could not stop while it happened.