Prevent negative heart recovery from future restore times
This commit is contained in:
parent
c29599daaa
commit
d967d11672
@ -165,5 +165,23 @@ describe('hearts-service', () => {
|
||||
expect(db.update).toHaveBeenCalledOnce();
|
||||
expect(vi.mocked(db.update).mock.results[0]?.value.set).toHaveBeenCalledWith({ heartsRemaining: 0 });
|
||||
});
|
||||
|
||||
it('does not turn hearts negative when last restore time is in the future', async () => {
|
||||
vi.mocked(db.select).mockReturnValueOnce(
|
||||
selectReturning([
|
||||
{
|
||||
tier: 'free',
|
||||
heartsRemaining: 0,
|
||||
heartsLastRestore: new Date(Date.now() + 13 * 30 * 60_000).toISOString(),
|
||||
},
|
||||
]) as never,
|
||||
);
|
||||
|
||||
const { getHearts } = await import('../../../services/progress/hearts-service.js');
|
||||
const result = await getHearts('user-1');
|
||||
|
||||
expect(result.remaining).toBe(0);
|
||||
expect(db.update).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -62,7 +62,8 @@ export async function getHearts(userId: string): Promise<HeartsInfo> {
|
||||
// Calculate auto-restore
|
||||
if (lastMs !== null && remaining < MAX_FREE_HEARTS) {
|
||||
const elapsed = Date.now() - lastMs;
|
||||
const restored = Math.floor(elapsed / RESTORE_INTERVAL_MS);
|
||||
// 服务器时间回拨或历史脏数据可能让 lastRestore 落在未来;恢复次数不能为负。
|
||||
const restored = Math.max(0, Math.floor(elapsed / RESTORE_INTERVAL_MS));
|
||||
remaining = Math.min(remaining + restored, MAX_FREE_HEARTS);
|
||||
|
||||
if (restored > 0) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user