64 lines
2.1 KiB
TypeScript
64 lines
2.1 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
import { getServerSession } from 'next-auth'
|
|
import { authOptions } from '@/lib/auth'
|
|
import { connectToDatabase } from '@/lib/mongodb'
|
|
import { ObjectId } from 'mongodb'
|
|
|
|
export async function GET() {
|
|
try {
|
|
const session = await getServerSession(authOptions)
|
|
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
}
|
|
|
|
const { db } = await connectToDatabase()
|
|
const user = await db.collection('users').findOne({ _id: new ObjectId(session.user.id) })
|
|
|
|
if (!user) {
|
|
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
|
}
|
|
|
|
const portfolioWithCoins = await Promise.all(
|
|
(user.portfolio || []).map(async (item: any) => {
|
|
const coin = await db.collection('coins').findOne({ _id: new ObjectId(item.coinId) })
|
|
if (!coin) return null
|
|
|
|
const currentValue = item.amount * coin.price
|
|
const costBasis = item.amount * item.avgBuyPrice
|
|
const pnl = currentValue - costBasis
|
|
const pnlPercent = costBasis > 0 ? (pnl / costBasis) * 100 : 0
|
|
|
|
return {
|
|
...item,
|
|
coin: {
|
|
_id: coin._id.toString(),
|
|
name: coin.name,
|
|
ticker: coin.ticker,
|
|
image: coin.image,
|
|
price: coin.price,
|
|
priceHistory: coin.priceHistory?.slice(-24) || [],
|
|
},
|
|
currentValue,
|
|
pnl,
|
|
pnlPercent,
|
|
}
|
|
})
|
|
)
|
|
|
|
const validPortfolio = portfolioWithCoins.filter(Boolean)
|
|
const totalPortfolioValue = validPortfolio.reduce((acc, item) => acc + item.currentValue, 0)
|
|
const totalPnL = validPortfolio.reduce((acc, item) => acc + item.pnl, 0)
|
|
|
|
return NextResponse.json({
|
|
portfolio: validPortfolio,
|
|
totalPortfolioValue,
|
|
totalPnL,
|
|
cashBalance: user.balance,
|
|
totalValue: user.balance + totalPortfolioValue,
|
|
})
|
|
} catch (error) {
|
|
console.error('Error fetching portfolio:', error)
|
|
return NextResponse.json({ error: 'Failed to fetch portfolio' }, { status: 500 })
|
|
}
|
|
}
|