Skip to content

Commit

Permalink
Merge pull request #102 from casesandberg/feature/new-profile
Browse files Browse the repository at this point in the history
New profile
  • Loading branch information
casesandberg authored Sep 16, 2024
2 parents 095bd9b + 30f185e commit df8ceb1
Show file tree
Hide file tree
Showing 34 changed files with 611 additions and 211 deletions.
25 changes: 25 additions & 0 deletions apps/api/app/api/users/[id]/balance/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { NextResponse } from 'next/server'
import type { SchemaResponse } from '@play-money/api-helpers'
import { getBalance, transformMarketBalancesToNumbers } from '@play-money/finance/lib/getBalances'
import { getUserPrimaryAccount } from '@play-money/users/lib/getUserPrimaryAccount'
import schema from './schema'

export const dynamic = 'force-dynamic'

export async function GET(
_req: Request,
{ params }: { params: unknown }
): Promise<SchemaResponse<typeof schema.get.responses>> {
try {
const { id } = schema.get.parameters.parse(params)
const userAccount = await getUserPrimaryAccount({ userId: id })
const balance = await getBalance({ accountId: userAccount.id, assetType: 'CURRENCY', assetId: 'PRIMARY' })

return NextResponse.json({
balance: transformMarketBalancesToNumbers([balance])[0],
})
} catch (error) {
console.log(error) // eslint-disable-line no-console -- Log error for debugging
return NextResponse.json({ error: 'Error processing request' }, { status: 500 })
}
}
16 changes: 16 additions & 0 deletions apps/api/app/api/users/[id]/balance/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { z } from 'zod'
import { ServerErrorSchema, createSchema } from '@play-money/api-helpers'

export default createSchema({
get: {
parameters: z.object({ id: z.string() }),
responses: {
200: z.object({
// TODO: Hookup with NetBalance
balance: z.object({}),
}),
404: ServerErrorSchema,
500: ServerErrorSchema,
},
},
})
38 changes: 38 additions & 0 deletions apps/api/app/api/users/[id]/positions/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { NextResponse } from 'next/server'
import type { SchemaResponse } from '@play-money/api-helpers'
import { getPositions } from '@play-money/finance/lib/getPositions'
import { getUserById } from '@play-money/users/lib/getUserById'
import schema from './schema'

export const dynamic = 'force-dynamic'

export async function GET(
req: Request,
{ params }: { params: unknown }
): Promise<SchemaResponse<typeof schema.GET.responses>> {
try {
const url = new URL(req.url)
const searchParams = new URLSearchParams(url.search)
const urlParams = Object.fromEntries(searchParams)

const { id, pageSize } = schema.GET.parameters.parse({ ...(params || {}), ...urlParams })

const user = await getUserById({ id })

const { positions } = await getPositions(
{
accountId: user.primaryAccountId,
},
{ field: 'updatedAt', direction: 'desc' },
{ take: pageSize ?? 25, skip: 0 }
)

return NextResponse.json({
positions,
})
} catch (error) {
console.log(error) // eslint-disable-line no-console -- Log error for debugging

return NextResponse.json({ error: 'Error processing request' }, { status: 500 })
}
}
16 changes: 16 additions & 0 deletions apps/api/app/api/users/[id]/positions/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { z } from 'zod'
import { ServerErrorSchema, createSchema } from '@play-money/api-helpers'
import { MarketOptionPositionSchema, UserSchema } from '@play-money/database'

export default createSchema({
GET: {
parameters: UserSchema.pick({ id: true }).extend({ pageSize: z.coerce.number().optional() }),
responses: {
200: z.object({
positions: z.array(MarketOptionPositionSchema),
}),
404: ServerErrorSchema,
500: ServerErrorSchema,
},
},
})
21 changes: 19 additions & 2 deletions packages/api-helpers/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import _ from 'lodash'
import { CommentWithReactions } from '@play-money/comments/lib/getComment'
import { Market, User } from '@play-money/database'
import { TransactionWithEntries, LeaderboardUser } from '@play-money/finance/types'
import { Market, MarketOptionPosition, User } from '@play-money/database'
import { NetBalanceAsNumbers } from '@play-money/finance/lib/getBalances'
import { TransactionWithEntries, LeaderboardUser, ExtendedMarketOptionPosition } from '@play-money/finance/types'
import { ExtendedMarket } from '@play-money/markets/types'

// TODO: @casesandberg Generate this from OpenAPI schema
Expand Down Expand Up @@ -339,6 +340,22 @@ export async function getUserTransactions({
)
}

export async function getUserPositions({
userId,
pageSize,
}: {
userId: string
pageSize?: number
}): Promise<{ positions: Array<ExtendedMarketOptionPosition> }> {
return apiHandler<{ positions: Array<ExtendedMarketOptionPosition> }>(
`${process.env.NEXT_PUBLIC_API_URL}/v1/users/${userId}/positions${pageSize ? `?pageSize=${pageSize}` : ''}`
)
}

export async function getUserBalance({ userId }: { userId: string }): Promise<{ balance: NetBalanceAsNumbers }> {
return apiHandler<{ balance: NetBalanceAsNumbers }>(`${process.env.NEXT_PUBLIC_API_URL}/v1/users/${userId}/balance`)
}

export async function getUserMarkets({ userId }: { userId: string }): Promise<{ markets: Array<ExtendedMarket> }> {
return apiHandler<{ markets: Array<ExtendedMarket> }>(
`${process.env.NEXT_PUBLIC_API_URL}/v1/markets?createdBy=${userId}`
Expand Down
1 change: 1 addition & 0 deletions packages/comments/lib/createComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export async function createComment({
commentCount: {
increment: 1,
},
updatedAt: new Date(),
},
})
}
Expand Down
2 changes: 1 addition & 1 deletion packages/comments/lib/updateComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function updateComment({ id, content }: { id: string; content?: str

const updatedComment = await db.comment.update({
where: { id },
data: updatedData,
data: { ...updatedData, updatedAt: new Date() },
})

return updatedComment
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- AlterTable
ALTER TABLE "Account" ALTER COLUMN "updatedAt" DROP DEFAULT;

-- AlterTable
ALTER TABLE "Balance" ALTER COLUMN "updatedAt" DROP DEFAULT;

-- AlterTable
ALTER TABLE "MarketOptionPosition" ALTER COLUMN "updatedAt" DROP DEFAULT;

-- AlterTable
ALTER TABLE "Transaction" ALTER COLUMN "updatedAt" DROP DEFAULT;
8 changes: 4 additions & 4 deletions packages/database/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ model Transaction {
initiatorId String?
initiator User? @relation(fields: [initiatorId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
updatedAt DateTime @updatedAt
batchId String?
batch TransactionBatch? @relation(fields: [batchId], references: [id])
marketId String?
Expand Down Expand Up @@ -282,7 +282,7 @@ model Account {
balances Balance[]
positions MarketOptionPosition[]
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

model Balance {
Expand All @@ -296,7 +296,7 @@ model Balance {
marketId String?
market Market? @relation(fields: [marketId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index(fields: [accountId, assetType, assetId, marketId])
}
Expand All @@ -313,7 +313,7 @@ model MarketOptionPosition {
quantity Decimal
value Decimal
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique(fields: [accountId, optionId])
@@index(fields: [accountId, optionId])
Expand Down
4 changes: 4 additions & 0 deletions packages/database/scripts/backfill-counts-on-markets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async function main() {
},
data: {
liquidityCount: data._sum.amount?.toNumber(),
updatedAt: new Date(),
},
})
console.log(`Successfully added liquidity count to market with id: ${market.id}`)
Expand Down Expand Up @@ -94,6 +95,7 @@ async function main() {
},
data: {
uniqueTradersCount: data.length,
updatedAt: new Date(),
},
})
console.log(`Successfully added unique traders count to market with id: ${market.id}`)
Expand Down Expand Up @@ -130,6 +132,7 @@ async function main() {
},
data: {
uniquePromotersCount: data.length,
updatedAt: new Date(),
},
})
console.log(`Successfully added unique promoters count to market with id: ${market.id}`)
Expand Down Expand Up @@ -162,6 +165,7 @@ async function main() {
},
data: {
commentCount: data._count,
updatedAt: new Date(),
},
})
console.log(`Successfully added comments count to market with id: ${market.id}`)
Expand Down
1 change: 1 addition & 0 deletions packages/database/scripts/backfill-market-amm-accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ async function main() {
type: 'MARKET_CLEARING' as const,
},
},
updatedAt: new Date(),
},
})
console.log(`Successfully created account for market with id: ${market.id}`)
Expand Down
1 change: 1 addition & 0 deletions packages/database/scripts/backfill-user-accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async function main() {
type: 'USER',
},
},
updatedAt: new Date(),
},
})
console.log(`Successfully created account for user with id: ${user.id}`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ async function main() {
where: { id: noOption.id },
data: {
createdAt: new Date(noOption.createdAt.getTime() + 1),
updatedAt: new Date(),
},
})

Expand Down
48 changes: 48 additions & 0 deletions packages/finance/lib/getPositions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import db from '@play-money/database'
import { ExtendedMarketOptionPosition } from '../types'

interface PositionsFilterOptions {
accountId?: string
}

interface SortOptions {
field: string
direction: 'asc' | 'desc'
}

interface PaginationOptions {
skip: number
take: number
}

export async function getPositions(
filters: PositionsFilterOptions = {},
sort: SortOptions = { field: 'createdAt', direction: 'desc' },
pagination: PaginationOptions = { skip: 0, take: 10 }
): Promise<{ positions: Array<ExtendedMarketOptionPosition>; total: number }> {
const [positions, total] = await Promise.all([
db.marketOptionPosition.findMany({
where: {
accountId: filters.accountId,
value: { gt: 0 },
},
include: {
market: true,
option: true,
},
orderBy: {
[sort.field]: sort.direction,
},
skip: pagination.skip,
take: pagination.take,
}),
db.marketOptionPosition.count({
where: {
accountId: filters.accountId,
value: { gt: 0 },
},
}),
])

return { positions, total }
}
7 changes: 6 additions & 1 deletion packages/finance/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Market, MarketOption, Transaction, TransactionEntry, User } from '@play-money/database'
import { Market, MarketOption, MarketOptionPosition, Transaction, TransactionEntry, User } from '@play-money/database'

export type TransactionEntryInput = Pick<
TransactionEntry,
Expand All @@ -20,3 +20,8 @@ export type LeaderboardUser = {
total: number
rank: number
}

export type ExtendedMarketOptionPosition = MarketOptionPosition & {
market: Market
option: MarketOption
}
14 changes: 7 additions & 7 deletions packages/markets/components/MarketBalanceBreakdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ export function MarketBalanceBreakdown({
{positions.map((position) => {
const option = options.find((option) => option.id === position.optionId)!
const value = new Decimal(position.value).toDecimalPlaces(4)
const cost = new Decimal(position.value).toDecimalPlaces(4)
const change = value.sub(cost).div(cost).times(100).toNumber()
const cost = new Decimal(position.cost).toDecimalPlaces(4)
const change = value.sub(cost).div(cost).times(100).round().toNumber()
const changeLabel = `(${change > 0 ? '+' : ''}${change}%)`

return value.toNumber() ? (
<Tooltip key={position.optionId}>
<TooltipTrigger className="flex w-full justify-between text-xs text-muted-foreground">
<div className="flex items-center gap-1">
<div className="size-2 rounded-md" style={{ backgroundColor: option.color }} />
<span className="font-mono">{option.name}</span>
<TooltipTrigger className="flex w-full justify-between gap-2 text-xs text-muted-foreground">
<div className="flex gap-1">
<div className="mt-1 size-2 flex-shrink-0 rounded-md" style={{ backgroundColor: option.color }} />
<span className="line-clamp-2 font-mono">{option.name}</span>
</div>
<div className="flex gap-2">
{change ? (
Expand All @@ -76,7 +76,7 @@ export function MarketBalanceBreakdown({
</div>
</TooltipTrigger>
<TooltipContent className="max-w-sm" align="start">
<div className="line-clamp-2">{option.name}</div>
<div>{option.name}</div>
<div className="text-xs text-muted-foreground">
Cost: {new Decimal(position.cost).toDecimalPlaces(4).toString()}
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/markets/lib/addLiquidity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export async function addLiquidity({
where: { id: marketId },
data: {
uniquePromotersCount: { increment: amount.toNumber() },
updatedAt: new Date(),
},
})
}
Expand Down
2 changes: 2 additions & 0 deletions packages/markets/lib/createMarket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export async function createMarket({
},
data: {
marketId: createdMarket.id,
updatedAt: new Date(),
},
}),
db.account.update({
Expand All @@ -122,6 +123,7 @@ export async function createMarket({
},
data: {
marketId: createdMarket.id,
updatedAt: new Date(),
},
}),
])
Expand Down
1 change: 1 addition & 0 deletions packages/markets/lib/createMarketBuyTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export async function createMarketBuyTransaction({
liquidityCount: {
increment: amount.toNumber(),
},
updatedAt: new Date(),
},
}),
])
Expand Down
1 change: 1 addition & 0 deletions packages/markets/lib/createMarketLiquidityTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export async function createMarketLiquidityTransaction({
liquidityCount: {
increment: amount.toNumber(),
},
updatedAt: new Date(),
},
})
const balances = await updateMarketBalances({ ...txParams, marketId })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export async function createMarketResolveLossTransactions({
decrement: quantity.toNumber(),
},
value: 0,
updatedAt: new Date(),
},
})
}),
Expand Down
Loading

0 comments on commit df8ceb1

Please sign in to comment.