feat: extend user API with contribution history and verified count
This commit is contained in:
+94
-1
@@ -1,7 +1,7 @@
|
||||
import { Elysia, t } from "elysia"
|
||||
import { auth } from "@/lib/auth"
|
||||
import { db } from "@/lib/db/index"
|
||||
import { user, performanceEntries } from "@/lib/db/schema"
|
||||
import { user, performanceEntries, games, gameVersions, hardware } from "@/lib/db/schema"
|
||||
import { eq, sql } from "drizzle-orm"
|
||||
|
||||
export const userRoutes = new Elysia({ prefix: "/user" })
|
||||
@@ -32,6 +32,14 @@ export const userRoutes = new Elysia({ prefix: "/user" })
|
||||
.from(performanceEntries)
|
||||
.where(eq(performanceEntries.userId, params.id))
|
||||
|
||||
// Count verified entries
|
||||
const [{ count: verifiedEntries }] = await db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(performanceEntries)
|
||||
.where(
|
||||
sql`${performanceEntries.userId} = ${params.id} AND ${performanceEntries.verifiedAt} IS NOT NULL`
|
||||
)
|
||||
|
||||
// Reputation = contributions * 10 (simple formula for now)
|
||||
const reputation = contributions * 10
|
||||
|
||||
@@ -39,6 +47,7 @@ export const userRoutes = new Elysia({ prefix: "/user" })
|
||||
return {
|
||||
...publicProfile,
|
||||
contributions,
|
||||
verifiedEntries,
|
||||
reputation,
|
||||
verified: emailVerified,
|
||||
}
|
||||
@@ -85,10 +94,20 @@ export const userRoutes = new Elysia({ prefix: "/user" })
|
||||
.from(performanceEntries)
|
||||
.where(eq(performanceEntries.userId, session.user.id))
|
||||
|
||||
// Count verified entries
|
||||
const [{ count: verifiedEntries }] = await db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(performanceEntries)
|
||||
.where(
|
||||
sql`${performanceEntries.userId} = ${session.user.id} AND ${performanceEntries.verifiedAt} IS NOT NULL`
|
||||
)
|
||||
|
||||
return {
|
||||
...profile,
|
||||
contributions,
|
||||
verifiedEntries,
|
||||
reputation: contributions * 10,
|
||||
verified: profile.emailVerified,
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -111,3 +130,77 @@ export const userRoutes = new Elysia({ prefix: "/user" })
|
||||
return sessions
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/profile/:id/contributions",
|
||||
async ({ params, query, set }) => {
|
||||
const [profile] = await db
|
||||
.select({ id: user.id })
|
||||
.from(user)
|
||||
.where(eq(user.id, params.id))
|
||||
.limit(1)
|
||||
|
||||
if (!profile) {
|
||||
set.status = 404
|
||||
return { error: "User not found" }
|
||||
}
|
||||
|
||||
const limit = Math.min(Number(query.limit) || 10, 50)
|
||||
const offset = Number(query.offset) || 0
|
||||
|
||||
const entries = await db
|
||||
.select({
|
||||
id: performanceEntries.id,
|
||||
fpsAvg: performanceEntries.fpsAvg,
|
||||
fpsLow: performanceEntries.fpsLow,
|
||||
fpsHigh: performanceEntries.fpsHigh,
|
||||
hardwareSlug: performanceEntries.hardwareSlug,
|
||||
hardwareName: hardware.name,
|
||||
fsrVersion: performanceEntries.fsrVersion,
|
||||
frameGenMethod: performanceEntries.frameGenMethod,
|
||||
verifiedAt: performanceEntries.verifiedAt,
|
||||
createdAt: performanceEntries.createdAt,
|
||||
gameTitle: games.title,
|
||||
gameId: games.id,
|
||||
gameHeaderImage: games.headerImage,
|
||||
})
|
||||
.from(performanceEntries)
|
||||
.innerJoin(
|
||||
gameVersions,
|
||||
eq(performanceEntries.versionId, gameVersions.id),
|
||||
)
|
||||
.innerJoin(games, eq(gameVersions.gameId, games.id))
|
||||
.innerJoin(
|
||||
hardware,
|
||||
eq(performanceEntries.hardwareSlug, hardware.slug),
|
||||
)
|
||||
.where(eq(performanceEntries.userId, params.id))
|
||||
.orderBy(sql`${performanceEntries.createdAt} DESC`)
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
|
||||
const [{ count: total }] = await db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(performanceEntries)
|
||||
.where(eq(performanceEntries.userId, params.id))
|
||||
|
||||
return {
|
||||
data: entries.map((e) => ({
|
||||
...e,
|
||||
createdAt: e.createdAt.toISOString(),
|
||||
verifiedAt: e.verifiedAt?.toISOString() ?? null,
|
||||
})),
|
||||
total,
|
||||
limit,
|
||||
offset,
|
||||
}
|
||||
},
|
||||
{
|
||||
params: t.Object({
|
||||
id: t.String(),
|
||||
}),
|
||||
query: t.Object({
|
||||
limit: t.Optional(t.String()),
|
||||
offset: t.Optional(t.String()),
|
||||
}),
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user