I did this in the wrong order.
At least, that was my first thought.
I was building a small project that checks images and documents for privacy risks. The backend came first, then the API, then a frontend that finally made it feel like an actual service.
Somewhere along the way, I realized something.
I had built quite a lot before properly organizing the requirements and documentation.
Normally, I would expect the order to look more like this:
requirements → design → implementation → testing → documentation
Mine looked closer to this:
build → break something → fix it → build more → test it → finally organize everything
Not exactly textbook development.
But writing the documentation afterwards turned out to be more useful than I expected.
The README became a way to inspect the project
At first, I thought I was just writing down what I had already built.
Instead, I kept finding things that were unclear.
What does this API actually guarantee?
What configuration is required before running the project?
What happens when an external dependency is unavailable?
Which parts have actually been tested?
Would someone other than me know how to start this project?
These are simple questions.
They become much harder to ignore when you have to explain the project in plain English.
And that was probably the most useful part.
Documentation stopped being something I needed to finish after development.
It became another form of testing.
AI made building faster, but that created a different problem
I also used AI quite heavily while building.
ChatGPT, Claude, and coding tools made it much easier to move from an idea to working code.
That part was great.
But faster implementation also meant I could move past decisions without really stopping to organize them.
A configuration works, so I move on.
An endpoint returns the right response, so I move on.
Docker starts successfully, so I move on.
Then deployment comes.
Suddenly all the small things I skipped become visible again.
Environment variables.
Ports.
Database configuration.
Build commands.
Health checks.
Logs.
Security settings.
Things that looked like small details on localhost started feeling much more important once I tried to get the application outside my own machine.
That was the point where I started thinking less about:
“Does this code work?”
and more about:
“Is this actually ready to leave localhost?”
There is a bigger difference between those two questions than I expected.
A working MVP is not the same as a shippable MVP
I used to think of an MVP mainly in terms of features.
If the core function works, the MVP works.
I still think that is partly true.
But there is another stage after that.
The application has to survive being run somewhere other than your laptop.
Someone needs to know how to configure it.
You need to know when it has failed.
Secrets should not be sitting in the repository.
The build should be reproducible.
The production environment should not depend on something you happened to configure manually three days ago and already forgot about.
None of these things are particularly exciting.
They are also exactly the things I kept running into.
So I started writing them down.
Not as another tutorial.
Just as a checklist I wanted for myself the next time I reached this stage.
That checklist became its own project
Eventually those notes turned into a small release workflow.
I made a lightweight version public on GitHub:
Spring Boot Release Checklist
It is a practical pre-release checklist for Spring Boot MVPs moving from localhost to production.
The idea is simple:
before calling an MVP ready, go through the things that are easy to miss when most of your attention has been on making the feature work.
I later expanded the same idea into a more structured 58-page deployment runbook, but the GitHub checklist remains the lightweight public version.
I did not originally plan to make a product out of it.
It came from repeatedly asking myself the same question while building:
“What am I forgetting before I ship this?”
I still don't think building first is the correct order
I would not turn this into advice like:
“Forget requirements. Just start coding.”
That would be the wrong lesson.
If anything, doing it backwards showed me why the earlier steps exist.
But there was something valuable about documenting a project after I had actually struggled with it.
The checklist was no longer theoretical.
Every item reminded me of something I had needed, forgotten, broken, or had to go back and check.
Maybe next time my process will be a little cleaner.
Probably not perfectly clean.
And that's fine.
I'm still learning by making things.
I keep more notes about development, AI tools, deployment, and the things that break along the way on the Nocklock blog.
You can also see the projects I'm building on GitHub