Streak & uniques bonus in transaction
This commit is contained in:
parent
62f20694bf
commit
c6a60a6678
|
@ -78,8 +78,6 @@ export const onCreateBet = functions
|
||||||
await notifyFills(bet, contract, eventId, bettor)
|
await notifyFills(bet, contract, eventId, bettor)
|
||||||
await updateBettingStreak(bettor, bet, contract, eventId)
|
await updateBettingStreak(bettor, bet, contract, eventId)
|
||||||
|
|
||||||
await firestore.collection('users').doc(bettor.id).update({ lastBetTime })
|
|
||||||
|
|
||||||
await revalidateStaticProps(getContractPath(contract))
|
await revalidateStaticProps(getContractPath(contract))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -89,23 +87,30 @@ const updateBettingStreak = async (
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
eventId: string
|
eventId: string
|
||||||
) => {
|
) => {
|
||||||
|
const { newBettingStreak } = await firestore.runTransaction(async (trans) => {
|
||||||
|
const userDoc = firestore.collection('users').doc(user.id)
|
||||||
|
const bettor = (await trans.get(userDoc)).data() as User
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
const currentDateResetTime = currentDateBettingStreakResetTime()
|
const currentDateResetTime = currentDateBettingStreakResetTime()
|
||||||
// if now is before reset time, use yesterday's reset time
|
// if now is before reset time, use yesterday's reset time
|
||||||
const lastDateResetTime = currentDateResetTime - DAY_MS
|
const lastDateResetTime = currentDateResetTime - DAY_MS
|
||||||
const betStreakResetTime =
|
const betStreakResetTime =
|
||||||
now < currentDateResetTime ? lastDateResetTime : currentDateResetTime
|
now < currentDateResetTime ? lastDateResetTime : currentDateResetTime
|
||||||
const lastBetTime = user?.lastBetTime ?? 0
|
const lastBetTime = bettor?.lastBetTime ?? 0
|
||||||
|
|
||||||
// If they've already bet after the reset time
|
// If they've already bet after the reset time
|
||||||
if (lastBetTime > betStreakResetTime) return
|
if (lastBetTime > betStreakResetTime) return { newBettingStreak: undefined }
|
||||||
|
|
||||||
const newBettingStreak = (user?.currentBettingStreak ?? 0) + 1
|
const newBettingStreak = (bettor?.currentBettingStreak ?? 0) + 1
|
||||||
// Otherwise, add 1 to their betting streak
|
// Otherwise, add 1 to their betting streak
|
||||||
await firestore.collection('users').doc(user.id).update({
|
await trans.update(userDoc, {
|
||||||
currentBettingStreak: newBettingStreak,
|
currentBettingStreak: newBettingStreak,
|
||||||
|
lastBetTime: bet.createdTime,
|
||||||
})
|
})
|
||||||
|
return { newBettingStreak }
|
||||||
|
})
|
||||||
|
if (!newBettingStreak) return
|
||||||
|
const result = await firestore.runTransaction(async (trans) => {
|
||||||
// Send them the bonus times their streak
|
// Send them the bonus times their streak
|
||||||
const bonusAmount = Math.min(
|
const bonusAmount = Math.min(
|
||||||
BETTING_STREAK_BONUS_AMOUNT * newBettingStreak,
|
BETTING_STREAK_BONUS_AMOUNT * newBettingStreak,
|
||||||
|
@ -117,8 +122,7 @@ const updateBettingStreak = async (
|
||||||
const bonusTxnDetails = {
|
const bonusTxnDetails = {
|
||||||
currentBettingStreak: newBettingStreak,
|
currentBettingStreak: newBettingStreak,
|
||||||
}
|
}
|
||||||
// TODO: set the id of the txn to the eventId to prevent duplicates
|
|
||||||
const result = await firestore.runTransaction(async (trans) => {
|
|
||||||
const bonusTxn: TxnData = {
|
const bonusTxn: TxnData = {
|
||||||
fromId: fromUserId,
|
fromId: fromUserId,
|
||||||
fromType: 'BANK',
|
fromType: 'BANK',
|
||||||
|
@ -130,41 +134,46 @@ const updateBettingStreak = async (
|
||||||
description: JSON.stringify(bonusTxnDetails),
|
description: JSON.stringify(bonusTxnDetails),
|
||||||
data: bonusTxnDetails,
|
data: bonusTxnDetails,
|
||||||
} as Omit<BettingStreakBonusTxn, 'id' | 'createdTime'>
|
} as Omit<BettingStreakBonusTxn, 'id' | 'createdTime'>
|
||||||
return await runTxn(trans, bonusTxn)
|
const { message, txn, status } = await runTxn(trans, bonusTxn)
|
||||||
|
return { message, txn, status, bonusAmount }
|
||||||
})
|
})
|
||||||
if (!result.txn) {
|
if (result.status != 'success') {
|
||||||
log("betting streak bonus txn couldn't be made")
|
log("betting streak bonus txn couldn't be made")
|
||||||
log('status:', result.status)
|
log('status:', result.status)
|
||||||
log('message:', result.message)
|
log('message:', result.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (result.txn)
|
||||||
await createBettingStreakBonusNotification(
|
await createBettingStreakBonusNotification(
|
||||||
user,
|
user,
|
||||||
result.txn.id,
|
result.txn.id,
|
||||||
bet,
|
bet,
|
||||||
contract,
|
contract,
|
||||||
bonusAmount,
|
result.bonusAmount,
|
||||||
newBettingStreak,
|
newBettingStreak,
|
||||||
eventId
|
eventId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateUniqueBettorsAndGiveCreatorBonus = async (
|
const updateUniqueBettorsAndGiveCreatorBonus = async (
|
||||||
contract: Contract,
|
oldContract: Contract,
|
||||||
eventId: string,
|
eventId: string,
|
||||||
bettor: User
|
bettor: User
|
||||||
) => {
|
) => {
|
||||||
|
const { newUniqueBettorIds } = await firestore.runTransaction(
|
||||||
|
async (trans) => {
|
||||||
|
const contractDoc = firestore.collection(`contracts`).doc(oldContract.id)
|
||||||
|
const contract = (await trans.get(contractDoc)).data() as Contract
|
||||||
let previousUniqueBettorIds = contract.uniqueBettorIds
|
let previousUniqueBettorIds = contract.uniqueBettorIds
|
||||||
|
|
||||||
|
const betsSnap = await trans.get(
|
||||||
|
firestore.collection(`contracts/${contract.id}/bets`)
|
||||||
|
)
|
||||||
if (!previousUniqueBettorIds) {
|
if (!previousUniqueBettorIds) {
|
||||||
const contractBets = (
|
const contractBets = betsSnap.docs.map((doc) => doc.data() as Bet)
|
||||||
await firestore.collection(`contracts/${contract.id}/bets`).get()
|
|
||||||
).docs.map((doc) => doc.data() as Bet)
|
|
||||||
|
|
||||||
if (contractBets.length === 0) {
|
if (contractBets.length === 0) {
|
||||||
log(`No bets for contract ${contract.id}`)
|
return { newUniqueBettorIds: undefined }
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
previousUniqueBettorIds = uniq(
|
previousUniqueBettorIds = uniq(
|
||||||
|
@ -182,18 +191,23 @@ const updateUniqueBettorsAndGiveCreatorBonus = async (
|
||||||
log(`Got ${previousUniqueBettorIds} unique bettors`)
|
log(`Got ${previousUniqueBettorIds} unique bettors`)
|
||||||
isNewUniqueBettor && log(`And a new unique bettor ${bettor.id}`)
|
isNewUniqueBettor && log(`And a new unique bettor ${bettor.id}`)
|
||||||
|
|
||||||
await firestore.collection(`contracts`).doc(contract.id).update({
|
await trans.update(contractDoc, {
|
||||||
uniqueBettorIds: newUniqueBettorIds,
|
uniqueBettorIds: newUniqueBettorIds,
|
||||||
uniqueBettorCount: newUniqueBettorIds.length,
|
uniqueBettorCount: newUniqueBettorIds.length,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to give a bonus for the creator's bet
|
// No need to give a bonus for the creator's bet
|
||||||
if (!isNewUniqueBettor || bettor.id == contract.creatorId) return
|
if (!isNewUniqueBettor || bettor.id == contract.creatorId)
|
||||||
|
return { newUniqueBettorIds: undefined }
|
||||||
|
|
||||||
|
return { newUniqueBettorIds }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (!newUniqueBettorIds) return
|
||||||
|
|
||||||
// Create combined txn for all new unique bettors
|
|
||||||
const bonusTxnDetails = {
|
const bonusTxnDetails = {
|
||||||
contractId: contract.id,
|
contractId: oldContract.id,
|
||||||
uniqueNewBettorId: bettor.id,
|
uniqueNewBettorId: bettor.id,
|
||||||
}
|
}
|
||||||
const fromUserId = isProd()
|
const fromUserId = isProd()
|
||||||
|
@ -202,12 +216,11 @@ const updateUniqueBettorsAndGiveCreatorBonus = async (
|
||||||
const fromSnap = await firestore.doc(`users/${fromUserId}`).get()
|
const fromSnap = await firestore.doc(`users/${fromUserId}`).get()
|
||||||
if (!fromSnap.exists) throw new APIError(400, 'From user not found.')
|
if (!fromSnap.exists) throw new APIError(400, 'From user not found.')
|
||||||
const fromUser = fromSnap.data() as User
|
const fromUser = fromSnap.data() as User
|
||||||
// TODO: set the id of the txn to the eventId to prevent duplicates
|
|
||||||
const result = await firestore.runTransaction(async (trans) => {
|
const result = await firestore.runTransaction(async (trans) => {
|
||||||
const bonusTxn: TxnData = {
|
const bonusTxn: TxnData = {
|
||||||
fromId: fromUser.id,
|
fromId: fromUser.id,
|
||||||
fromType: 'BANK',
|
fromType: 'BANK',
|
||||||
toId: contract.creatorId,
|
toId: oldContract.creatorId,
|
||||||
toType: 'USER',
|
toType: 'USER',
|
||||||
amount: UNIQUE_BETTOR_BONUS_AMOUNT,
|
amount: UNIQUE_BETTOR_BONUS_AMOUNT,
|
||||||
token: 'M$',
|
token: 'M$',
|
||||||
|
@ -215,21 +228,25 @@ const updateUniqueBettorsAndGiveCreatorBonus = async (
|
||||||
description: JSON.stringify(bonusTxnDetails),
|
description: JSON.stringify(bonusTxnDetails),
|
||||||
data: bonusTxnDetails,
|
data: bonusTxnDetails,
|
||||||
} as Omit<UniqueBettorBonusTxn, 'id' | 'createdTime'>
|
} as Omit<UniqueBettorBonusTxn, 'id' | 'createdTime'>
|
||||||
return await runTxn(trans, bonusTxn)
|
const { status, message, txn } = await runTxn(trans, bonusTxn)
|
||||||
|
return { status, newUniqueBettorIds, message, txn }
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.status != 'success' || !result.txn) {
|
if (result.status != 'success' || !result.txn) {
|
||||||
log(`No bonus for user: ${contract.creatorId} - status:`, result.status)
|
log(`No bonus for user: ${oldContract.creatorId} - status:`, result.status)
|
||||||
log('message:', result.message)
|
log('message:', result.message)
|
||||||
} else {
|
} else {
|
||||||
log(`Bonus txn for user: ${contract.creatorId} completed:`, result.txn?.id)
|
log(
|
||||||
|
`Bonus txn for user: ${oldContract.creatorId} completed:`,
|
||||||
|
result.txn?.id
|
||||||
|
)
|
||||||
await createUniqueBettorBonusNotification(
|
await createUniqueBettorBonusNotification(
|
||||||
contract.creatorId,
|
oldContract.creatorId,
|
||||||
bettor,
|
bettor,
|
||||||
result.txn.id,
|
result.txn.id,
|
||||||
contract,
|
oldContract,
|
||||||
result.txn.amount,
|
result.txn.amount,
|
||||||
newUniqueBettorIds,
|
result.newUniqueBettorIds,
|
||||||
eventId + '-unique-bettor-bonus'
|
eventId + '-unique-bettor-bonus'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user