ReviewOS

stacks/wildloop

Persist XP/scoring server-side (currently client session-only)

#947
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Problem

XP is computed and stored only in the browser (useRecorder.ts tb.addSessionXp, 120 + area/500). There is no XP column on User/UserStats, nothing persists it, and the leaderboard can't rank by it. XP resets on refresh.

Acceptance

  • Add an XP field (User or UserStats) and compute it server-side on claim/conquest.
  • Return xpGained in the conquest/claim response; frontend reads authoritative XP.
  • Optional XP-based leaderboard.
9 days ago

Done in 68d4c1f (+ review fixes in ee61af4).

  • New territory_stats.xp column; XP was previously a browser-only session counter that reset on refresh.
  • Server-side awards in resources/functions/xp.ts (claim 100+area/1k, conquest 150+areaGained/1k, defend 75), applied in ClaimTerritory + ProcessActivityConquest and accumulated into territory_stats.xp inside the idempotency guards so a replay can't double-award. Added an explicit 'claimed'-history guard to ClaimTerritory (the overlap 409 only blocks a re-claim while the territory is still active; an expired-then-re-claimed activity would otherwise double-award).
  • claim/conquest responses return xpGained + totalXp; the frontend run toast shows the authoritative '+N XP!' from the server, not the client counter.
  • XP leaderboard: GET /territories/leaderboard?type=xp; AthleteShow exposes stats.xp.

Verified by scripts/verify-xp.ts (15 checks: pure rewards, fresh-claim award matches the area formula + persists, claim & conquest replay award nothing, leaderboard ranks by xp, profile exposes xp). All 18 suites green.

Sign in to comment on this issue.