Bug Description
Two User fields are read by features but never written anywhere in the backend, so the features that depend on them are effectively dead.
CurrentStreak (models/user.go:32)
- Initialized to
0 at signup (auth.go:98, auth.go:189)
- Read by the Streak5 badge check:
if user.CurrentStreak >= 5 in gamification_controller.go:349 and debatevsbot_controller.go:489
- Displayed on profile (
profile_controller.go:120, :274)
- Never incremented — no
$inc/$set on currentStreak exists anywhere in the codebase.
- Result: streak is permanently
0, so >= 5 is never true → the Streak5 badge can never be earned, even though it's defined in code and shown in the UI.
LastActivityDate (models/user.go:33)
- Read by the "Experts Online" stat:
leaderboard.go:182 filters {"lastActivityDate": {"$gte": activeThreshold}} (active within last 30 min)
- Displayed on profile (
profile_controller.go:122)
- Never written — not even initialized at signup.
- Result:
lastActivityDate is the zero-value time.Time for every user. The leaderboard query is lastActivityDate >= threshold OR updatedAt >= threshold, so that first clause never matches and the whole stat silently falls back to updatedAt — which changes on any profile update, not on actual debate activity. "Experts Online" measures the wrong thing.
In short: the reads are wired up, the writes were never implemented. Both fields need to be updated when a user is active (e.g. on completing a debate / meaningful activity) — incrementing/resetting currentStreak based on day boundaries, and setting lastActivityDate = now.
Steps to Reproduce
- Create an account and use the app actively over several days (complete debates, etc.).
- Check your profile —
currentStreak stays 0 regardless of daily activity.
- Reach any amount of activity — the Streak5 badge is never awarded because
CurrentStreak never rises above 0.
- Check the "Experts Online" count on the leaderboard — it does not reflect
lastActivityDate (that field is never set); it only ever reflects updatedAt.
- Search the backend:
grep -rn "currentStreak\|lastActivityDate" backend --include=*.go shows reads and a signup-time 0, but no update logic.
Logs and Screenshots
$ grep -rn "currentStreak|CurrentStreak" backend --include=*.go
backend/controllers/auth.go:98: CurrentStreak: 0,
backend/controllers/auth.go:189: CurrentStreak: 0,
backend/controllers/gamification_controller.go:349: if user.CurrentStreak >= 5 && ...
backend/controllers/debatevsbot_controller.go:489: if user.CurrentStreak >= 5 && ...
backend/controllers/profile_controller.go:120,274: "currentStreak": user.CurrentStreak
backend/models/user.go:32: CurrentStreak int ...
→ read + init-to-0 only; never incremented
$ grep -rn "lastActivityDate|LastActivityDate" backend --include=*.go
backend/controllers/leaderboard.go:182: {"lastActivityDate": bson.M{"$gte": activeThreshold}}
backend/controllers/profile_controller.go:122: "lastActivityAt": user.LastActivityDate
backend/models/user.go:33: LastActivityDate time.Time ...
→ read only; never written
Environment Details
- Files: backend/models/user.go (fields), backend/controllers/auth.go (init), gamification_controller.go & debatevsbot_controller.go (Streak5 read), leaderboard.go (active filter read), profile_controller.go (display)
- Backend: Go / MongoDB
- Branch: main
- Note: purely a missing-write-path bug; no schema change needed, the fields already exist — they just need to be updated on user activity
Impact
Medium - Feature works but has issues
Code of Conduct
Bug Description
Two
Userfields are read by features but never written anywhere in the backend, so the features that depend on them are effectively dead.CurrentStreak(models/user.go:32)0at signup (auth.go:98,auth.go:189)if user.CurrentStreak >= 5ingamification_controller.go:349anddebatevsbot_controller.go:489profile_controller.go:120,:274)$inc/$setoncurrentStreakexists anywhere in the codebase.0, so>= 5is never true → the Streak5 badge can never be earned, even though it's defined in code and shown in the UI.LastActivityDate(models/user.go:33)leaderboard.go:182filters{"lastActivityDate": {"$gte": activeThreshold}}(active within last 30 min)profile_controller.go:122)lastActivityDateis the zero-valuetime.Timefor every user. The leaderboard query islastActivityDate >= threshold OR updatedAt >= threshold, so that first clause never matches and the whole stat silently falls back toupdatedAt— which changes on any profile update, not on actual debate activity. "Experts Online" measures the wrong thing.In short: the reads are wired up, the writes were never implemented. Both fields need to be updated when a user is active (e.g. on completing a debate / meaningful activity) — incrementing/resetting
currentStreakbased on day boundaries, and settinglastActivityDate = now.Steps to Reproduce
currentStreakstays 0 regardless of daily activity.CurrentStreaknever rises above 0.lastActivityDate(that field is never set); it only ever reflectsupdatedAt.grep -rn "currentStreak\|lastActivityDate" backend --include=*.goshows reads and a signup-time0, but no update logic.Logs and Screenshots
$ grep -rn "currentStreak|CurrentStreak" backend --include=*.go
backend/controllers/auth.go:98: CurrentStreak: 0,
backend/controllers/auth.go:189: CurrentStreak: 0,
backend/controllers/gamification_controller.go:349: if user.CurrentStreak >= 5 && ...
backend/controllers/debatevsbot_controller.go:489: if user.CurrentStreak >= 5 && ...
backend/controllers/profile_controller.go:120,274: "currentStreak": user.CurrentStreak
backend/models/user.go:32: CurrentStreak int ...
→ read + init-to-0 only; never incremented
$ grep -rn "lastActivityDate|LastActivityDate" backend --include=*.go
backend/controllers/leaderboard.go:182: {"lastActivityDate": bson.M{"$gte": activeThreshold}}
backend/controllers/profile_controller.go:122: "lastActivityAt": user.LastActivityDate
backend/models/user.go:33: LastActivityDate time.Time ...
→ read only; never written
Environment Details
Impact
Medium - Feature works but has issues
Code of Conduct