Whetstone.
Sign in
All courses
dddIntermediate

Domain-driven design, the Fusion way

A crash course in domain-driven design that starts from zero and takes you to fluent. Part one teaches the concepts through the lens you already have (NestJS, NextJS, TypeScript): entities versus value objects, aggregates that own their invariants, the anaemic-domain trap, and errors as values. Part two applies them to the real Fusion backend and the exact conventions its PRs are reviewed against. Part three walks the real review comments you received (from Mustafa, Sergii, Nick, and Nisha) and decodes what each one meant. You leave able to design it right up front, and able to read your own reviews.

26 lessons 317 min
DDCrash course
Curriculum

26 lessons across 9 modules

Capstone

Refactor a NestJS-style blob into the Fusion idiom

Here is code a Nest/Next developer would write on instinct, and that Fusion review would send straight back:

csharp
public class NoteService
{
    private readonly FusionDbContext _db;
    public NoteService(FusionDbContext db) => _db = db;

    public async Task<FlightNote> SaveNote(string flightKey, string body)
    {
        if (string.IsNullOrWhiteSpace(flightKey))
            throw new ArgumentException("flight key required");
        if (body.Length > 4000)
            throw new ArgumentException("too long");
        var row = new FlightNote { EjdpUniqueFlightKey = flightKey, Body = body };
        _db.FlightNotes.Add(row);
        await _db.SaveChangesAsync();
        return row;
    }
}

Refactor it into the Fusion shape from memory:

  1. A FlightNoteVo value object: private constructor, public static Result<FlightNoteVo> Create(string? key, string? body) that trims and validates, accumulating both failures. No exceptions.
  2. A SaveFlightNote use case: a sealed class, a ctor-injected IFlightNoteRepository port, an Execute(request, ct) returning Task<Result<...>>. It builds the VO, and on success taps the repository.
  3. An IFlightNoteRepository port (application layer) with a Save/SaveMany method, implemented by a persistence adapter that maps the VO to a DBO and calls SaveChangesAsync — and never calls Create.
  4. Rename it: there is no NoteService in Fusion. The use case is verb-first (SaveFlightNote); no Service/Manager/Provider.

Then run it past the anti-pattern checklist yourself: exceptions became Result? invalid VO unconstructable? logic out of the use case? layers pointing inward? When you can do that whole refactor without looking, the review stops calling it slop.

This is the same blob you'll meet in Module 1, Lesson 1 as "what slop is." By the time you reach it here you'll have the vocabulary to name every problem and the instinct to have designed it right the first time.

Your progress0%

0 of 26 lessons complete

ddd
csharp
dotnet
fusion
architecture