Kairos started as a class project with one idea: treating time as something you owe. If you left a task half done, it added minutes of "productive debt" and Gemini wrote a stoic reflection. It has had two versions, and the interesting part is why I moved from one to the other.
The first version depended on the server
It was a Flutter app with Provider that talked to a FastAPI server. The server stored tasks and debt, and one endpoint, "the confessional", asked Gemini for the reflection. It also had geofencing, to tie tasks to a place. It worked, but offline it was useless, and an app for organising your day has to open without signal.
The rewrite: data on the phone first
In the second version, tasks are stored on the phone with Realm, so they can be created and completed offline. Each one carries a sync flag, and when there's a session and a network, pending ones go up to Supabase.
Supabase replaced FastAPI: PostgreSQL with Row Level Security, so each user can only read and write their own data without coding that check into every request. My own server no longer added anything.
The Gemini key never goes on the phone
The AI is called from Supabase Edge Functions. One takes the tasks and returns them sorted by priority; if Gemini fails, it returns them as they were, so the app is never left waiting.
Organised by feature, testable without the interface
Tasks, focus mode, habits and stats, each with data, logic and screen kept apart. Bloc handles state and GetIt the dependencies, which lets me test the logic, such as the task and focus-mode Blocs, without starting the interface.
What was left behind
Geofencing and time debt. The database already has the debt table and the reflection function, but the app doesn't use them yet: I preferred a solid offline base to dragging along features from the old server.
What I learned: architecture gets paid for later
Putting the server at the centre was the easy choice at first; putting the phone at the centre is what makes the app useful day to day. Rebuilding it was costly, but it taught me to judge every decision by what it costs later.
