Skip to content

Commit

Permalink
Fix User Positions Pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
casesandberg committed Feb 3, 2025
1 parent ec213fe commit fb17f25
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 99 deletions.
21 changes: 5 additions & 16 deletions apps/api/app/api/v1/users/[id]/positions/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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 { getUserPositions } from '@play-money/users/lib/getUserPositions'
import schema from './schema'

export const dynamic = 'force-dynamic'
Expand All @@ -15,24 +15,13 @@ export async function GET(
const searchParams = new URLSearchParams(url.search)
const urlParams = Object.fromEntries(searchParams)

const { id, pageSize, status } = schema.get.parameters.parse({ ...(params || {}), ...urlParams })
const { id: userId, status, ...paginationParams } = schema.get.parameters.parse({ ...(params || {}), ...urlParams })

const user = await getUserById({ id })
await getUserById({ id: userId })

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

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

Expand Down
25 changes: 14 additions & 11 deletions apps/api/app/api/v1/users/[id]/positions/schema.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { z } from 'zod'
import { ApiEndpoints, ServerErrorSchema } from '@play-money/api-helpers'
import { MarketOptionPositionSchema, UserSchema } from '@play-money/database'
import {
ApiEndpoints,
createPaginatedResponseSchema,
paginationSchema,
ServerErrorSchema,
} from '@play-money/api-helpers'
import { MarketOptionPositionSchema } from '@play-money/database'

export default {
get: {
summary: 'Get positions for a user',
parameters: UserSchema.pick({ id: true }).extend({
pageSize: z.coerce.number().optional(),
status: z.enum(['active', 'closed', 'all']).optional(),
}),
parameters: z
.object({
id: z.string(),
status: z.enum(['active', 'closed', 'all']).optional(),
})
.merge(paginationSchema),
responses: {
200: z.object({
data: z.object({
positions: z.array(MarketOptionPositionSchema),
}),
}),
200: createPaginatedResponseSchema(MarketOptionPositionSchema),
404: ServerErrorSchema,
500: ServerErrorSchema,
},
Expand Down
228 changes: 167 additions & 61 deletions apps/api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,6 @@
]
}
},
"pageSize": {
"type": [
"number",
"null"
]
},
"username": {
"type": "string"
},
Expand Down Expand Up @@ -265,14 +259,6 @@
"name": "transactionType",
"in": "path"
},
"pageSize": {
"schema": {
"$ref": "#/components/schemas/pageSize"
},
"required": false,
"name": "pageSize",
"in": "path"
},
"username": {
"schema": {
"$ref": "#/components/schemas/username"
Expand Down Expand Up @@ -2159,6 +2145,106 @@
}
}
},
"/v1/lists/[id]/graph": {
"get": {
"summary": "Get the graph for a List of Markets",
"parameters": [
{
"$ref": "#/components/parameters/id"
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"startAt": {
"type": "string"
},
"endAt": {
"type": "string"
},
"markets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"probability": {
"type": "number"
}
},
"required": [
"id",
"probability"
]
}
}
},
"required": [
"startAt",
"endAt",
"markets"
]
}
}
},
"required": [
"data"
]
}
}
}
},
"404": {
"description": "Resource not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
},
"required": [
"error"
]
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
},
"required": [
"error"
]
}
}
}
}
}
}
},
"/v1/lists/[id]/markets": {
"post": {
"summary": "Create a market in a list",
Expand Down Expand Up @@ -6949,10 +7035,19 @@
"$ref": "#/components/parameters/id"
},
{
"$ref": "#/components/parameters/pageSize"
"$ref": "#/components/parameters/status"
},
{
"$ref": "#/components/parameters/status"
"$ref": "#/components/parameters/cursor"
},
{
"$ref": "#/components/parameters/limit"
},
{
"$ref": "#/components/parameters/sortField"
},
{
"$ref": "#/components/parameters/sortDirection"
}
],
"responses": {
Expand All @@ -6964,60 +7059,71 @@
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"positions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "cuid"
},
"accountId": {
"type": "string"
},
"marketId": {
"type": "string"
},
"optionId": {
"type": "string"
},
"cost": {},
"quantity": {},
"value": {},
"createdAt": {
"type": [
"string",
"null"
]
},
"updatedAt": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"accountId",
"marketId",
"optionId",
"createdAt",
"updatedAt"
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "cuid"
},
"accountId": {
"type": "string"
},
"marketId": {
"type": "string"
},
"optionId": {
"type": "string"
},
"cost": {},
"quantity": {},
"value": {},
"createdAt": {
"type": [
"string",
"null"
]
},
"updatedAt": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"accountId",
"marketId",
"optionId",
"createdAt",
"updatedAt"
]
}
},
"pageInfo": {
"type": "object",
"properties": {
"hasNextPage": {
"type": "boolean"
},
"endCursor": {
"type": "string"
},
"total": {
"type": "number"
}
},
"required": [
"positions"
"hasNextPage",
"total"
]
}
},
"required": [
"data"
"data",
"pageInfo"
]
}
}
Expand Down
21 changes: 16 additions & 5 deletions packages/api-helpers/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,24 @@ export async function getUserTransactions({ userId }: { userId: string }) {

export async function getUserPositions({
userId,
pageSize,
status,
...paginationParams
}: {
userId: string
pageSize?: number
}): Promise<{ data: { positions: Array<ExtendedMarketOptionPosition> } }> {
return apiHandler<{ data: { positions: Array<ExtendedMarketOptionPosition> } }>(
`${process.env.NEXT_PUBLIC_API_URL}/v1/users/${userId}/positions${pageSize ? `?pageSize=${pageSize}` : ''}`
status?: 'active' | 'closed' | 'all'
} & PaginationRequest): Promise<PaginatedResponse<ExtendedMarketOptionPosition>> {
const currentParams = new URLSearchParams(
JSON.parse(
JSON.stringify({
status,
...paginationParams,
})
)
)
const search = currentParams.toString()

return apiHandler<PaginatedResponse<ExtendedMarketOptionPosition>>(
`${process.env.NEXT_PUBLIC_API_URL}/v1/users/${userId}/positions${search ? `?${search}` : ''}`
)
}

Expand Down
13 changes: 12 additions & 1 deletion packages/finance/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Market, MarketOption, MarketOptionPosition, Transaction, TransactionEntry, User } from '@play-money/database'
import {
Market,
MarketOption,
MarketOptionPosition,
Transaction,
TransactionEntry,
User,
Account,
} from '@play-money/database'

export type TransactionEntryInput = Pick<
TransactionEntry,
Expand All @@ -24,4 +32,7 @@ export type LeaderboardUser = {
export type ExtendedMarketOptionPosition = MarketOptionPosition & {
market: Market
option: MarketOption
account: Account & {
user: User
}
}
Loading

0 comments on commit fb17f25

Please sign in to comment.