export const prerender = false; import type { APIRoute } from "astro"; import { desc, eq } from "drizzle-orm"; import { createDb } from "@/db"; import { comments, events, markets, positions, profiles, trades } from "@/db/schema"; export const GET: APIRoute = async ({ params, locals }) => { const runtime = locals.runtime as { env: { DATABASE_URL: string } }; const db = createDb(runtime.env.DATABASE_URL); const username = params.username; if (!username) { return Response.json({ error: "Missing username" }, { status: 400 }); } const [profile] = await db .select({ id: profiles.id, username: profiles.username, name: profiles.name, bio: profiles.bio, balance: profiles.balance, createdAt: profiles.createdAt, }) .from(profiles) .where(eq(profiles.username, username)); if (!profile) { return Response.json({ error: "Profile not found" }, { status: 404 }); } const [positionRows, recentComments, recentTrades] = await Promise.all([ db .select({ side: positions.side, shares: positions.shares, avgPrice: positions.avgPrice, realizedPnl: positions.realizedPnl, marketSlug: markets.slug, question: markets.question, poolYes: markets.poolYes, poolNo: markets.poolNo, eventSlug: events.slug, eventTitle: events.title, }) .from(positions) .innerJoin(markets, eq(positions.marketId, markets.id)) .innerJoin(events, eq(markets.eventId, events.id)) .where(eq(positions.profileId, profile.id)), db .select({ id: comments.id, body: comments.body, score: comments.score, createdAt: comments.createdAt, eventSlug: events.slug, eventTitle: events.title, }) .from(comments) .innerJoin(events, eq(comments.eventId, events.id)) .where(eq(comments.profileId, profile.id)) .orderBy(desc(comments.createdAt)) .limit(10), db .select({ action: trades.action, side: trades.side, shares: trades.shares, price: trades.price, amount: trades.amount, createdAt: trades.createdAt, marketSlug: markets.slug, question: markets.question, eventSlug: events.slug, }) .from(trades) .innerJoin(markets, eq(trades.marketId, markets.id)) .innerJoin(events, eq(markets.eventId, events.id)) .where(eq(trades.profileId, profile.id)) .orderBy(desc(trades.createdAt)) .limit(20), ]); const active = positionRows.filter((r) => parseFloat(r.shares) > 0); const closed = positionRows.filter((r) => parseFloat(r.shares) === 0 && parseFloat(r.realizedPnl) !== 0); let positionValue = 0; for (const p of active) { const poolYes = parseFloat(p.poolYes); const poolNo = parseFloat(p.poolNo); const currentPrice = p.side === "yes" ? poolNo / (poolYes + poolNo) : poolYes / (poolYes + poolNo); positionValue += currentPrice * parseFloat(p.shares); } const netWorth = parseFloat(profile.balance) + positionValue; return Response.json( { username: profile.username, name: profile.name, bio: profile.bio, netWorth: netWorth.toFixed(2), balance: profile.balance, createdAt: profile.createdAt, activePositions: active, closedPositions: closed, recentComments, recentTrades, }, { headers: { "Cache-Control": "public, s-maxage=60" } }, ); };