라이브 티커 · 갤럭시 검색 색인 · 주간 랭킹 스냅샷 · 연속 ZAP 상한 · 가입 행성 Zap · 성운 목표 · 랭킹 갱신 안내 · 행성 터치 반응
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { onCall } from 'firebase-functions/v2/https';
|
||||
import { onSchedule } from 'firebase-functions/v2/scheduler';
|
||||
import { getFirestore } from 'firebase-admin/firestore';
|
||||
import { getFirestore, Timestamp } from 'firebase-admin/firestore';
|
||||
import { logger } from 'firebase-functions';
|
||||
|
||||
import { callerUid, num, optionalStr, requireRole, str } from '../core/callable.js';
|
||||
@@ -66,11 +66,14 @@ export const fnPopSpend = onCall(async (req) => {
|
||||
fail(ERR.permissionDenied, '이 경로로 쓸 수 없는 사유입니다.');
|
||||
}
|
||||
const amount = positiveInt(num(req.data, 'amount'), 'amount');
|
||||
const { zapPop } = await loadPolicy();
|
||||
const { zapPop, zapMaxPerCall, zapMinIntervalMs } = await loadPolicy();
|
||||
const count = Math.floor(amount / zapPop);
|
||||
if (!Number.isSafeInteger(count) || count < 1 || count * zapPop !== amount) {
|
||||
fail(ERR.popVerifyFailed, `Zap 은 ${zapPop} POP 단위로만 보낼 수 있습니다.`);
|
||||
}
|
||||
// 연속 ZAP Rate Limit(FX §3) — 한 호출 상한과 호출 간격. 차감과 같은 트랜잭션에서 판정 · 기록한다.
|
||||
if (count > zapMaxPerCall) fail(ERR.questAbnormal, '한 번에 보낼 수 있는 Zap 횟수를 넘었습니다.');
|
||||
const limitRef = getFirestore().doc(`users/${uid}/rateLimits/zap`);
|
||||
return spendPop({
|
||||
uid,
|
||||
popType: popType(req.data),
|
||||
@@ -83,6 +86,13 @@ export const fnPopSpend = onCall(async (req) => {
|
||||
...(optionalStr(req.data, 'fandomId') ? { fandomId: str(req.data, 'fandomId') } : {}),
|
||||
// 묶음 횟수. 원장 행에 남아 「Zap N 회」를 세고, FPI 단위가 된다.
|
||||
count,
|
||||
precheck: async (tx) => {
|
||||
const last = (await tx.get(limitRef)).get('lastAt') as Timestamp | undefined;
|
||||
if (last && Date.now() - last.toMillis() < zapMinIntervalMs) {
|
||||
fail(ERR.questAbnormal, '너무 빠르게 Zap 했습니다. 잠시 뒤 다시 시도해 주세요.');
|
||||
}
|
||||
},
|
||||
alsoWrite: (tx) => tx.set(limitRef, { lastAt: Timestamp.now() }),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user