Case study · Personal product
Batchmeal
A batch-cooking meal-planning app, built as a demanding software-craftsmanship exercise: applying outside-in TDD, Domain-Driven Design and Clean Architecture for real, on a real product.
- 5
- bounded contexts
- ≈ 580
- tests (back + front)
- 90 %
- mutation testing (PIT + Stryker)
- 10
- ArchUnit rules
- 15+
- MCP tools exposed
Why this project is my best business card
No sales yet, and that's not the point. Batchmeal is the tangible demonstration of my standards: what you see here is exactly the rigour I bring to your business-critical applications.
Hexagonal architecture
The domain at the centre, pure, free of any framework. Inputs (HTTP, MCP) and outputs (database, external APIs) are adapters plugged in at the edges. The dependency rule always points toward the domain, never the other way.
A real domain, not CRUD
Computing energy needs is not a plain field: the Mifflin-St Jeor formula, EFSA activity coefficients (PAL), goal adjustment (lose / maintain / gain), then recalibration against a 28-day weigh-in history. Modelled with value objects and invariants, genuinely tested, isolated from the framework.
What it demonstrates
Clean Architecture enforced by the machine
Ten ArchUnit rules enforce the dependency rule at build time: domain and application layers free of Spring, JPA and Jackson, cross-context integration limited to a "published language". The architecture cannot silently drift.
Real Domain-Driven Design
Five bounded contexts (accounts, nutrition profiles, food catalogue, batch cooking, journal) plus a shared kernel, each a Maven module, communicating through domain events published after commit.
≈ 580 tests, outside-in TDD
RED, GREEN, refactor: ~200 back-end and ~380 front-end tests. 90% mutation testing (PIT on Java, Stryker on TypeScript), domain and use-case coverage (JaCoCo), no defensive code without a failing test first.
MCP-first delivery
Every use case exposed as an HTTP endpoint, an MCP tool for AI and an HTML widget, an approach designed for the age of agents.
MCP-first delivery, in detail
There is no web UI at first. Every use case ships in three forms at once, with a strict mapping:
- 1 use case
- 1 REST endpoint
- 1 MCP tool
- 1 HTML widget
The result: I drive the whole product from a chat client (MCP Inspector, ChatGPT, Claude Desktop) before writing a single line of React. The domain comes first, the UI later — an approach designed for the age of agents.
Tech stack
- Java 25
- Spring Boot 4.1
- Spring AI 2 (MCP)
- PostgreSQL 18
- Flyway
- Vavr (Either)
- ArchUnit
- JUnit 5
- PIT
- Testcontainers
- Pact
- JaCoCo
- Spotless
- React 19
- TypeScript 6
- Redux Toolkit
- Vite 8
- Tailwind CSS 4
- Playwright
- Stryker
- Biome
- Maven multi-module
- pnpm monorepo
- Docker multi-stage
- GitHub Actions
Industrialisation and CI
The project is tooled like a real production application:
- GitHub Actions continuous integration: build and tests on every pull request;
- conventional commits and automated releases (release-please);
- enforced formatting and linting (Spotless for Java, Biome for TypeScript);
- mutation testing (PIT, Stryker) and contract testing (Pact) for reliability.