In my blog post about Feature Planning, I omitted an important thing I do while developing. I split the feature work into plumbing and domain.
Domain: User, Post, FounderClub, Comments
Plumbing: Handle::RaceCondition, Formatter, KittyEvents, SearchObject
I define plumbing as the infrastructure code needed to enable the business logic/rules.
Domain logic is connected to the business and changes as often as the business does. It is more connected to the real world. Changes come from "outside", not from developers.
On the other hand, plumbing is in the developer's "land". It is all the utilities we have in the system that defines the underlining rules of the systems. I tend to find it more stable and, thus, more comfortable to generalize.
In Product Hunt, we often remove features. What we keep is all the plumbing we build for them, which makes our system better.
When we work on a feature, there are two types of things we usually do - plumbing and domain.
A domain is defined by business rules and changes often. Plumbing is the utilities we use to build our system. Those can be more generic and used in various places in our system. I call those "code improvements". The rules for making a good domain and plumbing code are different.