This week was less about adding shiny new features and more about writing clean, maintainable code. I realized that writing code isn’t just about making it work, it’s about making it safe, secure, and sustainable. A single misplaced file, a missing assert, or scattered logic might not break the app immediately, but it creates silent risks that will show up later. Week 4 became a turning point where I learned how to protect code, keep it organized, and respect clean architecture principles.
Secrets Don’t Belong in Public
Early in the week, I accidentally pushed a secret key into the assets/
folder, which meant it could end up on GitHub. It felt like a small mistake at first, after all, it was “just one file.” But then I learned: assets are public, databases are private.
What I changed:
- Moved it into database (safe, private).
- Updated the code to fetch it securely through
AssetRepo
. - Cached it so the key only loads once per lifecycle.
It was a wake-up call that security isn’t optional. Where you store something matters just as much as how you use it.
Asserts: The Invisible Bodyguards
In BouncerService
, I had removed an assert
thinking external validation was enough. But that one line was actually the last line of defense:
- UI layer prevents users from making invalid submissions.
- Service layer (assert) makes sure no invalid state ever touches the database.
Without the assert, the function trusted the outside world which is a dangerous assumption. Putting it back taught me that asserts aren’t “extra”, they’re invisible bodyguards protecting data integrity.
Organizing Logic Where It Belongs
Another mistake I caught was centralizing different business rules inside a BusinessLogicService
. On paper, it looked neat. In practice, it was messy. Bouncer logic, usher logic — all living in one file, far from the services they actually belonged to.
So I refactored:
- Bouncer logic into
BouncerService
- Usher logic into
UsherService
- Deleted
BusinessLogicService
completely
This reinforced a simple principle: related things should live together. Clean architecture isn’t about fewer files, it’s about making each file feel like home for its logic.
Service vs Remote: A Clearer Separation
I also learned the difference between a true service, remote and repository. I had created a JWTService
that parsed tokens, validated signatures, and loaded keys. But that wasn’t business logic but it was external data handling.
So I moved it under remote/
and renamed it JWTClient
. Along the way, I:
- Parsed JWTs using proper types (UUID for IDs, DateTime for timestamps).
- Used built-in library features (
jwt.jwtId
,jwt.issuer
) instead of manual payload parsing. - Check for issuer for extra security.
Avoid Redundancy & Write Idiomatic Code
Several times, I was caught writing unnecessary or verbose code:
- Extra null checks instead of using Dart’s
??
operator - Functions that wrapped single-line expressions (not worth it)
- Searching lists manually when the repository already had
selectPerformance()
- Over-engineering error messages instead of keeping them simple
I realized clean code is not about writing more, it’s about writing enough, no more, no less.
Reflections & Insights
- Security starts with respecting where data lives (public vs private).
- Clean architecture isn’t just theory, it prevents future bugs and makes code easier to navigate.
- Reading library documentation is just as important as writing code, the answers are often already there.
What’s Coming Up
Next week, I plan to go deeper into writing cleaner code with best practices. My focus will be:
- Understanding the role of each function in detail
- Reading and applying documentation properly
- Continue writing clear, concise, and non-redundant code
Because at the end of the day, good code works. But great code works, protects, and lasts.
0 Comments