fix: cumulative fund claims — deposits accumulate until claimed
Instead of expiring old claims, new deposits add to the existing pending claim's fiat_amount and extend the expiry. The claim email shows the updated total. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6c807afeb0
commit
f662881170
|
|
@ -1271,6 +1271,18 @@ export async function acceptFundClaim(token: string, userId: string): Promise<St
|
|||
return rowToFundClaim(rows[0]);
|
||||
}
|
||||
|
||||
export async function accumulateFundClaim(claimId: string, additionalAmount: string, expiresAt: number): Promise<StoredFundClaim | null> {
|
||||
const rows = await sql`
|
||||
UPDATE fund_claims
|
||||
SET fiat_amount = (COALESCE(fiat_amount::numeric, 0) + ${additionalAmount}::numeric)::text,
|
||||
expires_at = ${new Date(expiresAt)}
|
||||
WHERE id = ${claimId} AND status IN ('pending', 'resent')
|
||||
RETURNING *
|
||||
`;
|
||||
if (rows.length === 0) return null;
|
||||
return rowToFundClaim(rows[0]);
|
||||
}
|
||||
|
||||
export async function expireFundClaim(claimId: string): Promise<void> {
|
||||
await sql`UPDATE fund_claims SET status = 'expired', email = NULL WHERE id = ${claimId} AND status IN ('pending', 'resent')`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ import {
|
|||
getFundClaimByToken,
|
||||
getFundClaimsByEmailHash,
|
||||
acceptFundClaim,
|
||||
expireFundClaim,
|
||||
accumulateFundClaim,
|
||||
cleanExpiredFundClaims,
|
||||
sql,
|
||||
} from './db.js';
|
||||
|
|
@ -2926,17 +2926,30 @@ app.post('/api/internal/fund-claims', async (c) => {
|
|||
return c.json({ error: 'email and walletAddress are required' }, 400);
|
||||
}
|
||||
|
||||
const id = crypto.randomUUID();
|
||||
const token = generateToken();
|
||||
const emailHashed = await hashEmail(email);
|
||||
const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000; // 7 days
|
||||
|
||||
// Expire any existing pending claims for this email (one active claim per user)
|
||||
// Check for existing pending claim — accumulate deposits
|
||||
const existingClaims = await getFundClaimsByEmailHash(emailHashed);
|
||||
for (const ec of existingClaims) {
|
||||
await expireFundClaim(ec.id);
|
||||
if (existingClaims.length > 0 && fiatAmount) {
|
||||
const existing = existingClaims[0];
|
||||
const updated = await accumulateFundClaim(existing.id, fiatAmount, expiresAt);
|
||||
|
||||
let sent = false;
|
||||
try {
|
||||
const totalAmount = updated?.fiatAmount || fiatAmount;
|
||||
sent = await sendClaimEmail(email, existing.token, totalAmount, fiatCurrency || 'USD');
|
||||
} catch (err) {
|
||||
console.error('EncryptID: Failed to send claim email:', err);
|
||||
}
|
||||
|
||||
return c.json({ claimId: existing.id, accumulated: true, sent });
|
||||
}
|
||||
|
||||
// No existing claim — create new
|
||||
const id = crypto.randomUUID();
|
||||
const token = generateToken();
|
||||
|
||||
const claim = await createFundClaim({
|
||||
id,
|
||||
token,
|
||||
|
|
|
|||
Loading…
Reference in New Issue