Skip to content

Commit

Permalink
move access of txns from supabase client to api
Browse files Browse the repository at this point in the history
  • Loading branch information
sipec committed Sep 23, 2024
1 parent f87a7f5 commit 23ff7b5
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 118 deletions.
51 changes: 28 additions & 23 deletions backend/api/src/get-ad-analytics.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
import { APIHandler } from 'api/helpers/endpoint'
import { createSupabaseClient } from 'shared/supabase/init'
import { run } from 'common/supabase/utils'
import { createSupabaseDirectClient } from 'shared/supabase/init'
import { sumBy } from 'lodash'
import { log } from 'shared/utils'
import { from, select, where, renderSql } from 'shared/supabase/sql-builder'

export const getadanalytics: APIHandler<'get-ad-analytics'> = async (body) => {
const { contractId } = body
const db = createSupabaseClient()
const [{ data: adData }, { data: viewData }] = await Promise.all([
run(
db
.from('market_ads')
.select('id, funds, created_at, cost_per_view')
.eq('market_id', contractId)
),
run(
db
.from('user_contract_views')
.select('user_id, promoted_views, card_views')
.eq('contract_id', contractId)
.or('promoted_views.gt.0, card_views.gt.0')
),
const pg = createSupabaseDirectClient()

const adQuery = renderSql(
from('market_ads'),
select('id, funds, created_at, cost_per_view'),
where('market_id = ${contractId}', { contractId })
)

const viewQuery = renderSql(
from('user_contract_views'),
select('user_id, promoted_views, card_views'),
where('contract_id = ${contractId}', { contractId }),
where('promoted_views > 0 or card_views > 0')
)

const [adData, viewData] = await Promise.all([
pg.any(adQuery),
pg.any(viewQuery),
])

log({ adData, viewData })

const lastAdData = adData?.[0]

const { count: redeemCount } = await run(
db
.from('txns')
.select('*', { count: 'exact' })
.eq('category', 'MARKET_BOOST_REDEEM')
.eq('from_id', lastAdData?.id)
const redeemQuery = renderSql(
from('txns'),
select('count(*)'),
where(`category = 'MARKET_BOOST_REDEEM'`),
where('from_id = ${fromId}', { fromId: lastAdData?.id })
)
const redeemCount = lastAdData ? (await pg.one(redeemQuery)).count : 0

const promotedViewData = viewData?.filter((v) => v.promoted_views > 0)
const totalFunds = adData?.reduce((acc, v) => acc + v.funds, 0) ?? 0
return {
Expand Down
2 changes: 1 addition & 1 deletion common/src/api/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1661,7 +1661,7 @@ export const API = (_apiTypeCheck = {
txns: {
method: 'GET',
visibility: 'public',
authed: true,
authed: false,
props: z
.object({
token: z.string().optional(),
Expand Down
14 changes: 0 additions & 14 deletions common/src/supabase/bounties.ts

This file was deleted.

22 changes: 6 additions & 16 deletions web/components/add-funds-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,22 +310,12 @@ export const use24hrUsdPurchases = (userId: string) => {
const [purchases, setPurchases] = useState<Txn[]>([])

useEffect(() => {
run(
db
.from('txns')
.select()
.eq('category', 'MANA_PURCHASE')
.eq('to_id', userId)
).then((res) => {
setPurchases(res.data.map(convertTxn))
})
api('txns', {
category: 'MANA_PURCHASE',
toId: userId,
after: Date.now() - DAY_MS,
}).then(setPurchases)
}, [userId])

return (
sum(
purchases
.filter((t) => t.createdTime > Date.now() - DAY_MS)
.map((t) => t.amount)
) / 1000
)
return sum(purchases.map((t) => t.amount)) / 1000
}
11 changes: 8 additions & 3 deletions web/hooks/use-bounties.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Contract } from 'common/contract'
import { getBountyRewardCount } from 'common/supabase/bounties'
import { useState, useEffect } from 'react'
import { db } from 'web/lib/supabase/db'
import { api } from 'web/lib/api/api'

export const useBountyAwardCount = (contract: Contract) => {
const [count, setCount] = useState<number>(0)

useEffect(() => {
if (contract.outcomeType === 'BOUNTIED_QUESTION') {
getBountyRewardCount(db, contract.id).then(setCount)
// TODO: count in api?
Promise.all([
api('txns', { fromId: contract.id, category: 'BOUNTY_AWARD' }),
api('txns', { fromId: contract.id, category: 'BOUNTY_CANCELED' }),
]).then((results) => {
setCount(results.flat().length)
})
}
}, [contract.id])

Expand Down
24 changes: 10 additions & 14 deletions web/hooks/use-has-received-loan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import timezone from 'dayjs/plugin/timezone'
dayjs.extend(timezone)
import { usePersistentLocalState } from 'web/hooks/use-persistent-local-state'
import { useCallback, useEffect } from 'react'
import { run } from 'common/supabase/utils'
import { db } from 'web/lib/supabase/db'
import { api } from 'web/lib/api/api'

export const useHasReceivedLoanToday = (user: User) => {
const startOfDay = dayjs().tz('America/Los_Angeles').startOf('day').valueOf()
Expand All @@ -15,18 +14,15 @@ export const useHasReceivedLoanToday = (user: User) => {
>(undefined, `last-loan-${user.id}`)

const checkTxns = useCallback(async () => {
run(
db
.from('txns')
.select('created_time')
.eq('to_id', user.id)
.eq('category', 'LOAN')
.gte('created_time', new Date(startOfDay).toISOString())
.limit(1)
)
.then((res) => {
if (res.data.length > 0) {
setLastLoanReceived(new Date(res.data[0].created_time ?? 0).valueOf())
api('txns', {
category: 'LOAN',
toId: user.id,
after: startOfDay,
limit: 1,
})
.then((data) => {
if (data.length > 0) {
setLastLoanReceived(data[0].createdTime ?? 0)
} else {
setLastLoanReceived(0)
}
Expand Down
35 changes: 13 additions & 22 deletions web/hooks/use-mana-payments.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { useEffect, useState } from 'react'
import { ManaPayTxn } from 'common/txn'
import { db } from 'web/lib/supabase/db'
import { run } from 'common/supabase/utils'
import { sortBy, uniqBy } from 'lodash'
import { useEvent } from 'web/hooks/use-event'
import { convertTxn } from 'common/supabase/txns'
import { buildArray } from 'common/util/array'
import { api } from 'web/lib/api/api'

export const useManaPayments = (userId?: string) => {
const [manaPayments, setManaPayments] = useState<ManaPayTxn[] | undefined>(
Expand All @@ -13,16 +12,13 @@ export const useManaPayments = (userId?: string) => {
const load = useEvent(() => {
if (!userId) return

const query = db
.from('txns')
.select()
.eq('category', 'MANA_PAYMENT')
.or(`from_id.eq.${userId}, to_id.eq.${userId}`)
.order('created_time', { ascending: false } as any)
.limit(100)
run(query).then(({ data }) => {
const payments = (data.map(convertTxn) as ManaPayTxn[]) ?? []
setManaPayments((p) => uniqBy((p ?? []).concat(payments), 'id'))
Promise.all([
api('txns', { category: 'MANA_PAYMENT', fromId: userId }),
api('txns', { category: 'MANA_PAYMENT', toId: userId }),
]).then(([from, to]) => {
setManaPayments(
(p) => uniqBy(buildArray(p, from, to), 'id') as ManaPayTxn[]
)
})
})

Expand All @@ -38,15 +34,10 @@ export const useAllManaPayments = () => {
undefined
)
const load = useEvent(() => {
const query = db
.from('txns')
.select()
.eq('category', 'MANA_PAYMENT')
.order('created_time', { ascending: false } as any)
.limit(100)
run(query).then(({ data }) => {
const payments = (data.map(convertTxn) as ManaPayTxn[]) ?? []
setManaPayments((p) => uniqBy((p ?? []).concat(payments), 'id'))
api('txns', { category: 'MANA_PAYMENT' }).then((payments) => {
setManaPayments(
(p) => uniqBy(buildArray(p, payments), 'id') as ManaPayTxn[]
)
})
})

Expand Down
38 changes: 15 additions & 23 deletions web/lib/supabase/txns.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { uniq } from 'lodash'
import { db } from './db'
import { millisToTs, run, tsToMillis } from 'common/supabase/utils'
import { filterDefined } from 'common/util/array'
import { getDisplayUsers } from './users'
import { api } from '../api/api'
import { removeUndefinedProps } from 'common/util/object'

export async function getDonationsByCharity() {
const { data } = await db.rpc('get_donations_by_charity')
Expand All @@ -19,26 +20,24 @@ export async function getDonationsByCharity() {

export function getDonationsPageQuery(charityId: string) {
return async (p: { limit: number; after?: { ts: number } }) => {
let q = db
.from('txns')
.select(`from_id, created_time, amount, token`)
.eq('category', 'CHARITY')
.eq('to_id', charityId)
.order('created_time', { ascending: false } as any)
.limit(p.limit)
const txnData = await api(
'txns',
removeUndefinedProps({
category: 'CHARITY',
toId: charityId,
after: p.after?.ts,
limit: p.limit,
})
)

if (p.after?.ts) {
q = q.lt('created_time', millisToTs(p.after.ts))
}
const txnData = (await run(q)).data
const userIds = uniq(txnData.map((t) => t.from_id!))
const userIds = uniq(txnData.map((t) => t.fromId!))
const users = await getDisplayUsers(userIds)
const usersById = Object.fromEntries(
filterDefined(users).map((u) => [u.id, u])
)
const donations = txnData.map((t) => ({
user: usersById[t.from_id!],
ts: tsToMillis(t.created_time),
user: usersById[t.fromId!],
ts: t.createdTime,
amount:
t.token == 'M$'
? t.amount / 100
Expand All @@ -53,13 +52,6 @@ export function getDonationsPageQuery(charityId: string) {
}

export async function getMostRecentDonation() {
const { data } = await run(
db
.from('txns')
.select('from_id, to_id')
.eq('category', 'CHARITY')
.order('created_time', { ascending: false })
.limit(1)
)
const data = await api('txns', { category: 'CHARITY', limit: 1 })
return data[0]
}
4 changes: 2 additions & 2 deletions web/pages/charity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export async function getStaticProps() {
return {
props: {
totalsByCharity,
mostRecentCharityId: mostRecentDonation.to_id,
mostRecentDonor: await getUserById(mostRecentDonation.from_id!),
mostRecentCharityId: mostRecentDonation.toId,
mostRecentDonor: await getUserById(mostRecentDonation.fromId!),
},
revalidate: 60,
}
Expand Down

0 comments on commit 23ff7b5

Please sign in to comment.