import { jsonError } from '@/lib/server/http'; import { requireAuthenticatedSession } from '@/lib/server/auth-session'; import { recalculateHolding } from '@/lib/server/portfolio'; import { withStore } from '@/lib/server/store'; type Context = { params: Promise<{ id: string }>; }; function nowIso() { return new Date().toISOString(); } function asPositiveNumber(value: unknown) { const parsed = typeof value === 'number' ? value : Number(value); return Number.isFinite(parsed) && parsed > 0 ? parsed : null; } export async function PATCH(request: Request, context: Context) { const { session, response } = await requireAuthenticatedSession(); if (response) { return response; } const userId = session.user.id; const { id } = await context.params; const numericId = Number(id); if (!Number.isInteger(numericId) || numericId <= 0) { return jsonError('Invalid holding id'); } const payload = await request.json() as { shares?: number; avgCost?: number; currentPrice?: number; }; let found = false; let updated: unknown = null; await withStore((store) => { const index = store.holdings.findIndex((entry) => entry.id === numericId && entry.user_id === userId); if (index < 0) { return; } found = true; const existing = store.holdings[index]; const shares = asPositiveNumber(payload.shares) ?? Number(existing.shares); const avgCost = asPositiveNumber(payload.avgCost) ?? Number(existing.avg_cost); const currentPrice = asPositiveNumber(payload.currentPrice) ?? Number(existing.current_price ?? existing.avg_cost); const next = recalculateHolding({ ...existing, shares: shares.toFixed(6), avg_cost: avgCost.toFixed(6), current_price: currentPrice.toFixed(6), updated_at: nowIso(), last_price_at: nowIso() }); store.holdings[index] = next; updated = next; }); if (!found) { return jsonError('Holding not found', 404); } return Response.json({ holding: updated }); } export async function DELETE(_request: Request, context: Context) { const { session, response } = await requireAuthenticatedSession(); if (response) { return response; } const userId = session.user.id; const { id } = await context.params; const numericId = Number(id); if (!Number.isInteger(numericId) || numericId <= 0) { return jsonError('Invalid holding id'); } let removed = false; await withStore((store) => { const next = store.holdings.filter((holding) => !(holding.id === numericId && holding.user_id === userId)); removed = next.length !== store.holdings.length; store.holdings = next; }); if (!removed) { return jsonError('Holding not found', 404); } return Response.json({ success: true }); }