A production-grade task manager, built in the open to prove the standard I hold my work to
An authenticated project-and-task SaaS — Angular front to back against a Clean Architecture .NET API — built as an open portfolio piece rather than a client deliverable.
- Role
- Solo — product, architecture, build, deploy
- Duration
- Ongoing (2026)
- Team size
- 1
- Client type
- Personal project — open portfolio piece
- Stack
Context
TaskFlow is an authenticated web app for planning and tracking work — projects, tasks, and their state over time. It exists to be looked at as much as used: an end-to-end system I own outright, so I can show the full shape of a production build — architecture, testing, and deploy — without an NDA in the way.
The problem
A portfolio of anonymized client work proves I can build, but it can never be opened, cloned, or read line by line. I needed one system a prospective client can actually inspect — real auth, real data, real deploy — that demonstrates the standard the NDA-bound work is held to.
The interesting constraint is self-imposed: hold a solo side project to the same architectural discipline as a team system — enforced layering, a tested domain, and a pipeline — without that discipline becoming ceremony that stalls the build.
Constraints
- One developer, part-time — every abstraction has to earn its keep or it gets cut.
- Open by default: the code is meant to be read, so structure and naming carry weight they would not in a private repo.
- Single deploy artifact, hosted cheaply — no managed cloud services standing in for design decisions.
What I did
Layered the API on Clean Architecture
Domain, Application, Infrastructure, and API as separate projects with dependencies pointing inward — the same structure the Portfolio API mirrors — so business rules stay independent of EF Core, the web framework, and any one database.
Modeled the domain with real invariants
Entities and value objects enforce their own consistency rather than trusting callers, so an invalid task state cannot be constructed regardless of which handler reaches it.
Drove writes and reads down separate paths
Commands run through a validated handler pipeline; list/read queries take a thinner path built for the shape the UI actually renders, instead of forcing every read back through the write model.
Built the Angular client zoneless and standalone
Signals for state, standalone components, and SSR-friendly rendering — the same front-end architecture as this site — so the client stays fast and the whole thing is one coherent system, not two disconnected halves.
Key decisions & tradeoffs
Chose Clean Architecture with four projects over a single-project layered MVC app
- Because
- the point of the project is to demonstrate architecture that holds up under change; enforced boundaries make the intent legible to anyone reading the repo
- Tradeoff
- more moving parts and indirection up front than a solo CRUD app strictly needs — justified here because being read is a feature, not a side effect
Chose an explicit validated handler pipeline for writes over validation scattered across controllers
- Because
- every command hits the same validation and error-shaping boundary, so the API answers consistently and controllers stay thin
- Tradeoff
- a small amount of pipeline boilerplate per command, in exchange for one place to reason about how every write behaves
Chose a zoneless, signal-based Angular client over the default zone.js change-detection model
- Because
- change detection becomes explicit and cheap, which keeps the app fast and the data flow easy to follow
- Tradeoff
- gives up some of the "it just re-renders" ergonomics of zones, so state ownership has to be deliberate
Results
4 enforced layers
Architecture
Validated command pipeline
Write path
Zoneless · signal-driven
Front end
In active development
Status
What I’d do differently
The honest lesson so far is that architecture is cheap to add and expensive to remove: a couple of the boundaries earn themselves back the first time a change stays contained to one layer, and one or two are heavier than a solo project needs. When it ships, this section gets rewritten with what actually held up under real use — not what I hoped would.

