You are about to ask your agent to build the app, and it will happily generate whatever runs. Left alone, it pours every feature into one growing tangle that works on Friday and cannot be safely touched by Monday. This chapter gives you the one architectural decision that keeps the app changeable as it grows: build it as separate parts from the very first file.
3.1.1Separate concerns from the start
The oldest rule in software is separation of concerns: each part of the app does one job and knows as little as possible about the others. Payments handle payments, accounts handle accounts, and neither reaches into the other's internals.
You do not enforce this by hand. You tell the agent the app is made of distinct areas that each stay behind their own door. Then you hold it to that every single time it adds a feature.
3.1.2Start with a modular monolith
A module is one self-contained area of your app, all the code for one job kept together: accounts in one, billing in another. A modular monolith is one program you run and deploy as a single thing, split inside into those modules with clean lines between them. One app on the outside, many tidy rooms on the inside.
This is the right starting architecture for almost everyone. You get the simplicity of one codebase to run, build, and debug, plus the internal boundaries that let you change one area without disturbing the rest.
3.1.3Avoid the mud ball
Two failure modes sit on either side. The big ball of mud is what you get with no boundaries at all: every part reaches into every other, and one change ripples everywhere at once.
The opposite mistake is splitting the app into separate deployed services too early, premature microservices. A solo builder who does this trades a problem they have, organizing code, for problems they do not: networks between services, version mismatches, and failures spread across machines.
3.1.4A foundation that bends instead of breaks
Clean modules are what let the app bend instead of break. A new feature drops into the area it belongs to, and a bug stays contained to one room. You can also hand your agent one module at a time, without it needing the whole app in its head.
If you ever genuinely outgrow the single app, the boundaries you drew are the seams you cut along. A module with a clean edge lifts out into its own service; a mud ball has to be rewritten. You are not choosing against scale, you are earning the right to it later.
3.1.5Your data model already shows you the modules
You do not invent these boundaries, you read them off the plan you already wrote. Name each module after something your business talks about, accounts, billing, notifications, and never after a technology, so nothing ends up called services or helpers.
The entities you sketched in your data model cluster into three or four groups, and your user stories fall into the same groups. Start there and you are usually right the first time.
Two tests settle the rest. A module owns its own data and nothing outside it writes to that data, and two areas that always change together were one module all along.
This prompt draws the boundaries with you rather than for you:
Do this now: paste the prompt, hand over your data model and stories, and agree the three or four modules before your agent generates a line of the app.