A JWT-authenticated FastAPI habit tracker where the real engineering test is timezone-correct streak math, per-user ownership isolation, and idempotent concurrent writes -- not the CRUD scaffolding wrapped around them.
Nobody has started this yet — be first.
Weekly/monthly completion rate silently excludes today
GET /habits/{id}/stats is the number a user sees on any "how am I doing this week" screen. Right now, a check-in made today never counts toward this week's (or this month's) completion rate -- it only starts counting tomorrow. A user who checks in every single day will see their weekly completion rate permanently one day behind reality, which reads as "the app doesn't notice when I show up." This is exactly the kind of quiet correctness bug that erodes trust in a habit-tracking product without ever throwing an error -- nobody files a support ticket for "my percentage looks 1/7th too low," they just stop trusting the number.
About this project
A FastAPI backend for tracking daily habits: JWT-based registration and login, per-user habits each carrying their own IANA timezone, daily check-ins, and computed current/longest streaks plus a week/month completion-rate view -- the whole thing sitting on SQLAlchemy over SQLite and documented live at /docs.
The engineering center of gravity is compute_streaks, a small pure function that has to get three genuinely easy-to-miss things right at once: a gap must reset a streak to 1, not just fail to increment it; "haven't checked in yet today" must never be confused with "streak is broken" (the streak is anchored to yesterday until today's check-in actually lands); and "today" is defined per habit by that habit's own IANA timezone, not the server's UTC clock. Two more problems sit right next to it: is the single choke point every habit/check-in route trusts to enforce per-user ownership -- OWASP API1:2023 Broken Object Level Authorization territory the moment that one predicate goes missing -- and has to survive two overlapping requests for the same habit+day racing past its own existence check without crashing, backed only by a database and no locking.
Add GET /habits/{id}/checkins (check-in history)
Right now a user can see their current streak and longest streak, but not which days they actually checked in. Support cannot answer "why does my streak say 3, I thought I'd checked in more than that" without direct database access, because the API has no way to list the underlying dates. Any future UI feature that wants to render a calendar/heatmap view of a habit (a very standard habit-tracker UI pattern) is blocked on this -- it's the most-requested kind of "just let me see my own data" gap.
get_habit_for_usercreate_checkinUniqueConstraintSeven tickets (four bugs, three enhancements) are deliberately injected into an otherwise working, fully-tested codebase -- from a one-line off-by-one in the stats window and a pair of swapped response fields, up through a real IDOR (an ownership filter silently dropped from one query) and a genuine TOCTOU race in the check-in path. Each ticket has its own dedicated pytest file under practice_tickets/tests/, and two of them (the swapped streak fields and the IDOR) are severe enough to also break tests already in the project's own tests/ suite -- a second, independent signal that the fix is actually correct, not just locally green.