1fa2e350d7
Dependencies upgraded: - svelte 5.38→5.55, @sveltejs/kit 2.37→2.56, adapter-node 5.3→5.5 - mongoose 8→9, sharp 0.33→0.34, typescript 5→6 - lucide-svelte → @lucide/svelte 1.7 (Svelte 5 native package) - vite 7→8 with rolldown (build time 33s→14s) - Removed terser (esbuild/oxc default minifier is 20-100x faster) Infrastructure: - Removed Redis/ioredis cache layer — MongoDB handles caching natively - Deleted src/lib/server/cache.ts and all cache.get/set/invalidate usage - Removed redis-cli from deploy workflow, Redis env vars from .env.example Mongoose 9 migration: - Replaced deprecated `new: true` with `returnDocument: 'after'` (16 files) - Fixed strict query filter types for ObjectId/paymentId fields - Fixed season param type (string→number) in recipe API - Removed unused @ts-expect-error in WorkoutSession model
103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
import type { RequestHandler } from '@sveltejs/kit';
|
|
import { PaymentSplit } from '$models/PaymentSplit';
|
|
import { Payment } from '$models/Payment'; // Need to import Payment for populate to work
|
|
import { dbConnect } from '$utils/db';
|
|
import { error, json } from '@sveltejs/kit';
|
|
|
|
export const GET: RequestHandler = async ({ locals, url }) => {
|
|
const auth = await locals.auth();
|
|
if (!auth || !auth.user?.nickname) {
|
|
throw error(401, 'Not logged in');
|
|
}
|
|
|
|
const username = auth.user.nickname;
|
|
const includeAll = url.searchParams.get('all') === 'true';
|
|
|
|
await dbConnect();
|
|
|
|
try {
|
|
if (includeAll) {
|
|
const allSplits = await PaymentSplit.aggregate([
|
|
{
|
|
$group: {
|
|
_id: '$username',
|
|
totalOwed: { $sum: { $cond: [{ $gt: ['$amount', 0] }, '$amount', 0] } },
|
|
totalOwing: { $sum: { $cond: [{ $lt: ['$amount', 0] }, { $abs: '$amount' }, 0] } },
|
|
netBalance: { $sum: '$amount' }
|
|
}
|
|
},
|
|
{
|
|
$project: {
|
|
username: '$_id',
|
|
totalOwed: 1,
|
|
totalOwing: 1,
|
|
netBalance: 1,
|
|
_id: 0
|
|
}
|
|
}
|
|
]);
|
|
|
|
const currentUserBalance = allSplits.find(balance => balance.username === username) || {
|
|
username,
|
|
totalOwed: 0,
|
|
totalOwing: 0,
|
|
netBalance: 0
|
|
};
|
|
|
|
const result = {
|
|
currentUser: currentUserBalance,
|
|
allBalances: allSplits
|
|
};
|
|
|
|
return json(result);
|
|
|
|
} else {
|
|
const userSplits = await PaymentSplit.find({ username }).lean();
|
|
|
|
// Calculate net balance: negative = you are owed money, positive = you owe money
|
|
const netBalance = userSplits.reduce((sum, split) => sum + split.amount, 0);
|
|
|
|
const recentSplits = await PaymentSplit.aggregate([
|
|
{ $match: { username } },
|
|
{
|
|
$lookup: {
|
|
from: 'payments',
|
|
localField: 'paymentId',
|
|
foreignField: '_id',
|
|
as: 'paymentId'
|
|
}
|
|
},
|
|
{ $unwind: '$paymentId' },
|
|
{ $sort: { 'paymentId.date': -1, 'paymentId.createdAt': -1 } },
|
|
{ $limit: 30 }
|
|
]);
|
|
|
|
// For settlements, fetch the other user's split info
|
|
for (const split of recentSplits) {
|
|
if (split.paymentId && split.paymentId.category === 'settlement') {
|
|
// This is a settlement, find the other user
|
|
const otherSplit = await PaymentSplit.findOne({
|
|
paymentId: split.paymentId._id,
|
|
username: { $ne: username }
|
|
}).lean();
|
|
|
|
if (otherSplit) {
|
|
split.otherUser = otherSplit.username;
|
|
}
|
|
}
|
|
}
|
|
|
|
const result = {
|
|
netBalance,
|
|
recentSplits
|
|
};
|
|
|
|
return json(result);
|
|
}
|
|
|
|
} catch (e) {
|
|
console.error('Error calculating balance:', e);
|
|
throw error(500, 'Failed to calculate balance');
|
|
}
|
|
};
|