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(db.update).toHaveBeenCalledOnce();
|
||||||
expect(vi.mocked(db.update).mock.results[0]?.value.set).toHaveBeenCalledWith({ heartsRemaining: 0 });
|
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
|
// Calculate auto-restore
|
||||||
if (lastMs !== null && remaining < MAX_FREE_HEARTS) {
|
if (lastMs !== null && remaining < MAX_FREE_HEARTS) {
|
||||||
const elapsed = Date.now() - lastMs;
|
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);
|
remaining = Math.min(remaining + restored, MAX_FREE_HEARTS);
|
||||||
|
|
||||||
if (restored > 0) {
|
if (restored > 0) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user