chore: commit previously untracked runtime files (splits, auth, participants, shared)
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getCurrentUser } from "@/lib/auth";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const user = await getCurrentUser(req);
|
||||
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
return NextResponse.json(user);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { queryRaw } from "@/lib/db";
|
||||
|
||||
interface BalanceRow {
|
||||
participant_id: number;
|
||||
name: string;
|
||||
total_owed: number;
|
||||
transaction_count: number;
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
const { id } = await params;
|
||||
|
||||
const rows = await queryRaw<BalanceRow>(
|
||||
`SELECT ts.participant_id, p.name,
|
||||
SUM(t.amount * ts.share_percent / 100)::numeric(12,2) as total_owed,
|
||||
COUNT(*)::int as transaction_count
|
||||
FROM transaction_splits ts
|
||||
JOIN transactions t ON t.id = ts.transaction_id
|
||||
JOIN participants p ON p.id = ts.participant_id
|
||||
WHERE ts.participant_id = $1 AND ts.settled = false
|
||||
GROUP BY ts.participant_id, p.name`,
|
||||
[Number(id)]
|
||||
);
|
||||
|
||||
return NextResponse.json(
|
||||
rows[0] ?? { participant_id: Number(id), total_owed: 0, transaction_count: 0 }
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getParticipantBalances } from "@/lib/queries";
|
||||
import { getCurrentUser } from "@/lib/auth";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const user = await getCurrentUser(req);
|
||||
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const balances = await getParticipantBalances(user.id);
|
||||
return NextResponse.json(balances);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { queryRaw } from "@/lib/db";
|
||||
|
||||
export async function GET() {
|
||||
const participants = await prisma.participants.findMany({
|
||||
orderBy: { name: "asc" },
|
||||
});
|
||||
return NextResponse.json(participants);
|
||||
}
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const { name, email } = await req.json();
|
||||
if (!name?.trim()) {
|
||||
return NextResponse.json({ error: "name required" }, { status: 400 });
|
||||
}
|
||||
const participant = await prisma.participants.create({
|
||||
data: { name: name.trim(), email: email?.trim() || null },
|
||||
});
|
||||
return NextResponse.json(participant, { status: 201 });
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getSharedTransactions } from "@/lib/queries";
|
||||
import { getCurrentUser } from "@/lib/auth";
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const user = await getCurrentUser(req);
|
||||
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const transactions = await getSharedTransactions(user.id);
|
||||
return NextResponse.json(transactions);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/db";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const body = await req.json();
|
||||
const { participant_id, split_ids } = body as {
|
||||
participant_id?: number;
|
||||
split_ids?: number[];
|
||||
};
|
||||
|
||||
const now = new Date();
|
||||
|
||||
if (participant_id) {
|
||||
const result = await prisma.transaction_splits.updateMany({
|
||||
where: { participant_id, settled: false },
|
||||
data: { settled: true, settled_at: now },
|
||||
});
|
||||
return NextResponse.json({ settled: result.count });
|
||||
}
|
||||
|
||||
if (split_ids?.length) {
|
||||
const result = await prisma.transaction_splits.updateMany({
|
||||
where: { id: { in: split_ids }, settled: false },
|
||||
data: { settled: true, settled_at: now },
|
||||
});
|
||||
return NextResponse.json({ settled: result.count });
|
||||
}
|
||||
|
||||
return NextResponse.json({ error: "participant_id or split_ids required" }, { status: 400 });
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { queryRaw } from "@/lib/db";
|
||||
|
||||
interface SplitInput {
|
||||
participant_id: number;
|
||||
share_percent: number;
|
||||
}
|
||||
|
||||
interface SplitRow {
|
||||
id: number;
|
||||
transaction_id: number;
|
||||
participant_id: number;
|
||||
name: string;
|
||||
share_percent: number;
|
||||
settled: boolean;
|
||||
settled_at: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
const { id } = await params;
|
||||
const splits = await queryRaw<SplitRow>(
|
||||
`SELECT ts.*, p.name
|
||||
FROM transaction_splits ts
|
||||
JOIN participants p ON p.id = ts.participant_id
|
||||
WHERE ts.transaction_id = $1
|
||||
ORDER BY p.name`,
|
||||
[Number(id)]
|
||||
);
|
||||
return NextResponse.json(splits);
|
||||
}
|
||||
|
||||
export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
const { id } = await params;
|
||||
const transactionId = Number(id);
|
||||
const { splits } = (await req.json()) as { splits: SplitInput[] };
|
||||
|
||||
if (!splits || !Array.isArray(splits) || splits.length === 0) {
|
||||
return NextResponse.json({ error: "splits array required" }, { status: 400 });
|
||||
}
|
||||
|
||||
const total = splits.reduce((sum, s) => sum + Number(s.share_percent), 0);
|
||||
if (Math.abs(total - 100) > 0.01) {
|
||||
return NextResponse.json(
|
||||
{ error: `Shares must sum to 100%, got ${total}%` },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Replace all splits for this transaction atomically
|
||||
await prisma.$transaction([
|
||||
prisma.transaction_splits.deleteMany({ where: { transaction_id: transactionId } }),
|
||||
...splits.map((s) =>
|
||||
prisma.transaction_splits.create({
|
||||
data: {
|
||||
transaction_id: transactionId,
|
||||
participant_id: s.participant_id,
|
||||
share_percent: s.share_percent,
|
||||
},
|
||||
})
|
||||
),
|
||||
]);
|
||||
|
||||
const result = await queryRaw<SplitRow>(
|
||||
`SELECT ts.*, p.name FROM transaction_splits ts
|
||||
JOIN participants p ON p.id = ts.participant_id
|
||||
WHERE ts.transaction_id = $1 ORDER BY p.name`,
|
||||
[transactionId]
|
||||
);
|
||||
|
||||
return NextResponse.json(result);
|
||||
}
|
||||
Reference in New Issue
Block a user