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

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.