PayTrack started as a personal problem. I was working long hours at a construction job and had no clean way to track what I was actually earning after tax deductions. Spreadsheets felt clunky, generic finance apps were overkill, and nothing purpose-built existed. So I decided to engineer one myself.
Defining the Problem Space
Before writing a single line of code, I spent time mapping out exactly what the app needed to do. The core requirement was straightforward: given an hourly rate, hours worked, and a tax rate, compute net income accurately and store the records persistently. But the moment I started thinking about edge cases — overtime thresholds, partial weeks, varying deduction rules — the data model became genuinely interesting.
I settled on three primary entities: WorkSession, TaxProfile, and EarningsSummary. Each session would store raw hours and rate; the tax profile would hold the user's deduction configuration; and the summary would be a derived, on-demand computation rather than a stored value — keeping the database lean and the UI always in sync with the source data.
Stack Decisions
I chose Flutter for the UI layer. Cross-platform reach mattered less than the quality of the widget system — Jetpack Compose was tempting, but Flutter's declarative model and hot-reload cycle made iteration significantly faster during the design phase. For persistence, I used sqflite wrapped behind a repository abstraction, so swapping to Room or another backend later wouldn't require touching the business logic.
State management went through a few iterations. I started with setState for speed, then migrated the earnings flow to a ChangeNotifier + Provider pattern once the widget tree grew deep enough that prop-drilling became painful. Not the flashiest architecture, but pragmatic and easy to reason about at 1am after a long shift.
The Hard Parts
The trickiest engineering challenge was the tax calculation engine. Different regions apply deductions differently — flat rates, progressive brackets, employer-side contributions. I abstracted this into a TaxStrategy interface with pluggable implementations, which made testing each variant in isolation clean and gave a clear extension point for adding new regions later.
"The trickiest part wasn't the math — it was making the math feel invisible to the user."
UI polish consumed more time than expected. Material You's dynamic color system is genuinely powerful, but getting tonal surface containers to maintain contrast across both light and dark themes — especially with the palette randomizer — required careful use of on-primary-container and surface-container-high tokens rather than hardcoded hex values. A lesson I'll carry into every future project.
Shipping It
The Play Store pipeline was its own mini-project: generating a signed release build, writing the store listing, crafting screenshots that communicated value at a glance, and passing the policy review. Total time from first commit to live listing was just under four weeks, built entirely around a full-time day job.
PayTrack isn't a moonshot. It's a focused, well-engineered tool that solves one problem exceptionally well. If you work hourly and want clarity on your take-home pay, it does exactly that — nothing more, nothing less. Sometimes that's the hardest thing to build.