Update txn type

This commit is contained in:
James Grugett 2022-04-25 22:29:50 -04:00
parent 45cfa9bcc7
commit 7aa7271c9f
3 changed files with 47 additions and 40 deletions

View File

@ -1,4 +1,5 @@
export interface Charity {
id: string
slug: string // Note, slugs double as charity IDs
name: string
website: string
@ -232,7 +233,11 @@ export const charities: Charity[] = [
blurb:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
},
].map((charity) => ({
...charity,
slug: charity.name.replace(/\s/g, '-'),
}))
].map((charity) => {
const slug = charity.name.toLowerCase().replace(/\s/g, '-')
return {
...charity,
id: slug,
slug,
}
})

View File

@ -5,15 +5,10 @@ export type Txn = {
createdTime: number
fromId: string
// TODO: Do we really want to denormalize name/username/avatar here?
fromName: string
fromUsername: string
fromAvatarUrl?: string
fromType: 'user' | 'contract' | 'bank_of_manifold'
toId: string
toName: string
toUsername: string
toAvatarUrl?: string
toType: 'user' | 'contract' | 'charity' | 'bank_of_manifold'
amount: number

View File

@ -2,30 +2,44 @@ import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import { User } from '../../common/user'
import { Txn, TxnCategory, TxnData } from '../../common/txn'
import { Txn } from '../../common/txn'
import { removeUndefinedProps } from '../../common/util/object'
export const transact = functions.runWith({ minInstances: 1 }).https.onCall(
async (
data: {
amount: number
toId: string
category: TxnCategory
description?: string
txnData?: TxnData
},
context
) => {
const fromId = context?.auth?.uid
if (!fromId) return { status: 'error', message: 'Not authorized' }
export const transact = functions
.runWith({ minInstances: 1 })
.https.onCall(async (data: Exclude<Txn, 'id' | 'createdTime'>, context) => {
const userId = context?.auth?.uid
if (!userId) return { status: 'error', message: 'Not authorized' }
const { amount, toId, category, description, txnData } = data
const {
amount,
fromType,
fromId,
toId,
toType,
category,
description,
data: txnData,
} = data
if (fromType !== 'user')
return {
status: 'error',
message: "From type is only implemented for type 'user'.",
}
if (fromId !== userId)
return {
status: 'error',
message: 'Must be authenticated with userId equal to specified fromId.',
}
if (amount <= 0 || isNaN(amount) || !isFinite(amount))
return { status: 'error', message: 'Invalid amount' }
// run as transaction to prevent race conditions
// Run as transaction to prevent race conditions.
return await firestore.runTransaction(async (transaction) => {
const fromDoc = firestore.doc(`users/${fromId}`)
const fromDoc = firestore.doc(`users/${userId}`)
const fromSnap = await transaction.get(fromDoc)
if (!fromSnap.exists) {
return { status: 'error', message: 'User not found' }
@ -48,26 +62,20 @@ export const transact = functions.runWith({ minInstances: 1 }).https.onCall(
const newTxnDoc = firestore.collection(`txns/`).doc()
const txn: Txn = {
const txn: Txn = removeUndefinedProps({
id: newTxnDoc.id,
createdTime: Date.now(),
fromId,
fromName: fromUser.name,
fromUsername: fromUser.username,
fromAvatarUrl: fromUser.avatarUrl,
fromType,
toId,
toName: toUser.name,
toUsername: toUser.username,
toAvatarUrl: toUser.avatarUrl,
toType,
amount,
category,
description,
data: txnData,
}
})
transaction.create(newTxnDoc, txn)
transaction.update(fromDoc, { balance: fromUser.balance - amount })
@ -75,7 +83,6 @@ export const transact = functions.runWith({ minInstances: 1 }).https.onCall(
return { status: 'success', txnId: newTxnDoc.id }
})
}
)
})
const firestore = admin.firestore()