Technical challenges
The next stage of the Learning engine — technical interview preparation — depends on a structured interview-question JSON dataset that I haven't finished preparing yet. That's a content dependency, not an architecture problem: the scheduling engine, local data model, and Learning screens the feature would run on are already built and tested; what's missing is the actual question-bank content. Beyond that, the same two problems recurred across the rest of the app: keeping a Task's optional link to a Goal safe without a database foreign key, and making "should this task remind me right now" a single, testable rule rather than logic scattered across whatever triggers a task change.
How I approached it
Reminder eligibility is a single pure function that takes a task's current state and returns whether a reminder should exist right now — every code path that could change that answer calls the same function, so there is exactly one place that rule lives. The Goal/Task relationship is a deliberate soft reference: deleting a Goal clears the association on its Tasks first and only then removes the Goal itself, so a crash between those two steps can never leave an orphaned reference, without needing a database transaction for safety. The Learning engine's review scheduling is a small, self-contained spaced-repetition algorithm operating on plain data, kept separate from the repository and UI layers so it can be tested directly and reused for a new content category — like interview questions — once that content exists, without changing the scheduling logic itself.

