refactor: replace cleanup service with focused temp role service and fix daily streaks

This commit is contained in:
syntaxbullet
2026-01-07 11:04:34 +01:00
parent 4a1e72c5f3
commit ca392749e3
9 changed files with 206 additions and 341 deletions

View File

@@ -209,6 +209,15 @@ describe("economyService", () => {
expect(result.streak).toBe(1);
});
it("should preserve streak if cooldown is missing but user has a streak", async () => {
mockFindFirst
.mockResolvedValueOnce(undefined) // No cooldown
.mockResolvedValueOnce({ id: 1n, dailyStreak: 10 });
const result = await economyService.claimDaily("1");
expect(result.streak).toBe(11);
});
it("should prevent weekly bonus exploit by resetting streak", async () => {
// Mock user at streak 7.
// Mock time as 24h + 1m after expiry.

View File

@@ -68,8 +68,6 @@ export const economyService = {
claimDaily: async (userId: string, tx?: Transaction) => {
return await withTransaction(async (txFn) => {
const now = new Date();
const startOfDay = new Date(now);
startOfDay.setHours(0, 0, 0, 0);
// Check cooldown
const cooldown = await txFn.query.userTimers.findFirst({
@@ -90,17 +88,23 @@ export const economyService = {
});
if (!user) {
throw new Error("User not found"); // This might be system error because user should exist if authenticated, but keeping simple for now
throw new Error("User not found");
}
let streak = (user.dailyStreak || 0) + 1;
// If previous cooldown exists and expired more than 24h ago (meaning >48h since last claim), reduce streak by one for each day passed minimum 1
// Check if streak should be reset due to missing a day
if (cooldown) {
const timeSinceReady = now.getTime() - cooldown.expiresAt.getTime();
// If more than 24h passed since it became ready, they missed a full calendar day
if (timeSinceReady > 24 * 60 * 60 * 1000) {
streak = 1;
}
} else if ((user.dailyStreak || 0) > 0) {
// If no cooldown record exists but user has a streak,
// we'll allow one "free" increment to restore the timer state.
// This prevents unfair resets if timers were cleared/lost.
streak = (user.dailyStreak || 0) + 1;
} else {
streak = 1;
}