Denormalize betAmount
and betOutcome
fields on comments (#838)
* Create and use `betAmount` and `betOutcome` fields on comments * Be robust to ridiculous bet IDs on dev
This commit is contained in:
parent
a15230e7ab
commit
6ef2beed8f
|
@ -23,10 +23,16 @@ export type Comment<T extends AnyCommentType = AnyCommentType> = {
|
|||
type OnContract = {
|
||||
commentType: 'contract'
|
||||
contractId: string
|
||||
contractSlug: string
|
||||
contractQuestion: string
|
||||
answerOutcome?: string
|
||||
betId?: string
|
||||
|
||||
// denormalized from contract
|
||||
contractSlug: string
|
||||
contractQuestion: string
|
||||
|
||||
// denormalized from bet
|
||||
betAmount?: number
|
||||
betOutcome?: string
|
||||
}
|
||||
|
||||
type OnGroup = {
|
||||
|
|
|
@ -63,11 +63,15 @@ export const onCreateCommentOnContract = functions
|
|||
.doc(comment.betId)
|
||||
.get()
|
||||
bet = betSnapshot.data() as Bet
|
||||
|
||||
answer =
|
||||
contract.outcomeType === 'FREE_RESPONSE' && contract.answers
|
||||
? contract.answers.find((answer) => answer.id === bet?.outcome)
|
||||
: undefined
|
||||
|
||||
await change.ref.update({
|
||||
betOutcome: bet.outcome,
|
||||
betAmount: bet.amount,
|
||||
})
|
||||
}
|
||||
|
||||
const comments = await getValues<ContractComment>(
|
||||
|
|
69
functions/src/scripts/denormalize-comment-bet-data.ts
Normal file
69
functions/src/scripts/denormalize-comment-bet-data.ts
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Filling in the bet-based fields on comments.
|
||||
|
||||
import * as admin from 'firebase-admin'
|
||||
import { zip } from 'lodash'
|
||||
import { initAdmin } from './script-init'
|
||||
import {
|
||||
DocumentCorrespondence,
|
||||
findDiffs,
|
||||
describeDiff,
|
||||
applyDiff,
|
||||
} from './denormalize'
|
||||
import { log } from '../utils'
|
||||
import { Transaction } from 'firebase-admin/firestore'
|
||||
|
||||
initAdmin()
|
||||
const firestore = admin.firestore()
|
||||
|
||||
async function getBetComments(transaction: Transaction) {
|
||||
const allComments = await transaction.get(
|
||||
firestore.collectionGroup('comments')
|
||||
)
|
||||
const betComments = allComments.docs.filter((d) => d.get('betId'))
|
||||
log(`Found ${betComments.length} comments associated with bets.`)
|
||||
return betComments
|
||||
}
|
||||
|
||||
async function denormalize() {
|
||||
let hasMore = true
|
||||
while (hasMore) {
|
||||
hasMore = await admin.firestore().runTransaction(async (trans) => {
|
||||
const betComments = await getBetComments(trans)
|
||||
const bets = await Promise.all(
|
||||
betComments.map((doc) =>
|
||||
trans.get(
|
||||
firestore
|
||||
.collection('contracts')
|
||||
.doc(doc.get('contractId'))
|
||||
.collection('bets')
|
||||
.doc(doc.get('betId'))
|
||||
)
|
||||
)
|
||||
)
|
||||
log(`Found ${bets.length} bets associated with comments.`)
|
||||
const mapping = zip(bets, betComments)
|
||||
.map(([bet, comment]): DocumentCorrespondence => {
|
||||
return [bet!, [comment!]] // eslint-disable-line
|
||||
})
|
||||
.filter(([bet, _]) => bet.exists) // dev DB has some invalid bet IDs
|
||||
|
||||
const amountDiffs = findDiffs(mapping, 'amount', 'betAmount')
|
||||
const outcomeDiffs = findDiffs(mapping, 'outcome', 'betOutcome')
|
||||
log(`Found ${amountDiffs.length} comments with mismatched amounts.`)
|
||||
log(`Found ${outcomeDiffs.length} comments with mismatched outcomes.`)
|
||||
const diffs = amountDiffs.concat(outcomeDiffs)
|
||||
diffs.slice(0, 500).forEach((d) => {
|
||||
log(describeDiff(d))
|
||||
applyDiff(trans, d)
|
||||
})
|
||||
if (diffs.length > 500) {
|
||||
console.log(`Applying first 500 because of Firestore limit...`)
|
||||
}
|
||||
return diffs.length > 500
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
denormalize().catch((e) => console.error(e))
|
||||
}
|
|
@ -125,15 +125,12 @@ export function FeedComment(props: {
|
|||
} = props
|
||||
const { text, content, userUsername, userName, userAvatarUrl, createdTime } =
|
||||
comment
|
||||
let betOutcome: string | undefined,
|
||||
bought: string | undefined,
|
||||
money: string | undefined
|
||||
|
||||
const matchedBet = betsBySameUser.find((bet) => bet.id === comment.betId)
|
||||
if (matchedBet) {
|
||||
betOutcome = matchedBet.outcome
|
||||
bought = matchedBet.amount >= 0 ? 'bought' : 'sold'
|
||||
money = formatMoney(Math.abs(matchedBet.amount))
|
||||
const betOutcome = comment.betOutcome
|
||||
let bought: string | undefined
|
||||
let money: string | undefined
|
||||
if (comment.betAmount != null) {
|
||||
bought = comment.betAmount >= 0 ? 'bought' : 'sold'
|
||||
money = formatMoney(Math.abs(comment.betAmount))
|
||||
}
|
||||
|
||||
const [highlighted, setHighlighted] = useState(false)
|
||||
|
@ -148,7 +145,7 @@ export function FeedComment(props: {
|
|||
const { userPosition, outcome } = getBettorsLargestPositionBeforeTime(
|
||||
contract,
|
||||
comment.createdTime,
|
||||
matchedBet ? [] : betsBySameUser
|
||||
comment.betId ? [] : betsBySameUser
|
||||
)
|
||||
|
||||
return (
|
||||
|
@ -175,7 +172,7 @@ export function FeedComment(props: {
|
|||
username={userUsername}
|
||||
name={userName}
|
||||
/>{' '}
|
||||
{!matchedBet &&
|
||||
{!comment.betId != null &&
|
||||
userPosition > 0 &&
|
||||
contract.outcomeType !== 'NUMERIC' && (
|
||||
<>
|
||||
|
@ -194,7 +191,6 @@ export function FeedComment(props: {
|
|||
of{' '}
|
||||
<OutcomeLabel
|
||||
outcome={betOutcome ? betOutcome : ''}
|
||||
value={(matchedBet as any).value}
|
||||
contract={contract}
|
||||
truncate="short"
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue
Block a user