Why
Problems in software, shown one step at a time.
No write-ups with these tags.
Why Lean
Two promos landed on the same item and sold it below what we paid. Each was approved and reviewed on its own. Nobody checked what they do together.
Why DDD: bounded context
Every service is arranged its own way: its own directory layout, a muddle of terms, a wheel reinvented and the same mistake made for the hundredth time. What you know about one service does not carry over to the next — not for the author, not at review, not for whoever arrives a year later.
Why DDD: domain
The domain has been named in words, but in code it is still a struct with exported fields and `float64` for money. The domain rules live in the callers: each holds its own half, and one day one of them goes stale.
Why DDD: domain services
The late fee is calculated from the due date, the daily rate and the working calendar. It does not fit in the aggregate — the invoice would start knowing about calendars; it cannot go into the use case either — the rule would leave the domain, and the next caller would calculate it differently.
Why DDD: specification
The rule "the invoice is overdue" lives in three places and is named in none: a `WHERE` clause in the scheduler, a field in the read projection and the report for accounting. The first change to the rule reaches only one of the three.
Why DDD: applications && infrastructure
The use case, the storage and the incoming call spread across layers, and what each of them knows about the domain gets discovered in production: where the transaction started, who sent the fact, and why a subscriber learned about something that is not in the database.
Why DDD: transport && wiring
The use cases are written and the ports have implementations — and still the service cannot be called: JSON arrives from outside, and the use case expects domain entities. Nor is there anyone to assemble it into a running process: `cmd/` is empty.
Why CQRS
The use case takes five parameters, and nothing stops a call from mixing them up. Reading goes through the same aggregate: to show one row on a screen the service loads the whole invoice with all the rules reading does not need.
Why aggregate versioning
Two calls read the same invoice, each applied its own rule, both saved. What stayed in the database is whatever was written second — the first change is gone, and neither transaction noticed: both `UPDATE`s succeeded.
Why integration events
A domain fact went onto the bus as it was, with its own fields and types. A neighbouring service parsed it and built on it: renaming a field inside the domain now breaks somebody else's service, and we learn about it from their alerts.
Little's law
The arrival rate and the time an item spends in the system are on every dashboard. The third quantity — how many items are in the system — is the product of those two, yet it usually gets estimated separately and approximately. Hence pools sized by the number of users, and queue-depth thresholds that say nothing about waiting time.
System design: a scraping jobs service
A system design task arrives as a paragraph of text without a single number, and people start drawing the diagram in the first minute. Then it turns out the service has neither requirements nor estimates, and there is nothing to base the queue discussion on: nobody knows what load it has to handle.