refactor(db): migrate app pages and APIs from Prisma facade to Drizzle (4)

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-08-01 14:15:36 +02:00
1 parent 580972c0a0
commit 9aa4f331bf
40 files changed
+1259 -927

No files matched your search

+71 -51
View File
@@ -1,10 +1,21 @@
import {
and,
asc,
count,
desc,
eq,
inArray,
like,
or,
type SQL,
} from "drizzle-orm";
import { redirect } from "next/navigation";
import { getTranslations } from "next-intl/server";
import { StatusCard } from "@/components/admin/dashboard";
import { calcPagination, parseListParams } from "@/lib/admin-helpers";
import { db, User, WebsitePaypalTransactions } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { type TransactionRow, TransactionsTable } from "./transactions-table";
const PAID_STATUS = ["completed", "paid", "success", "approved"] as const;
@@ -33,15 +44,6 @@ function formatAmount(amount: number, currency: string): string {
return `${value} ${currency}`;
}
const SORT_MAP: Record<string, any> = {
id: { id: "desc" },
amount: { amount: "desc" },
date: { createdAt: "desc" },
status: { status: "desc" },
package: { description: "desc" },
payer: { userId: "desc" },
};
export default async function AdminTransactions({
searchParams,
}: {
@@ -57,14 +59,20 @@ export default async function AdminTransactions({
const parsed = parseListParams(new URLSearchParams(raw));
const statusFilter = raw.filter_status ?? "";
const where: any = {};
const conditions: SQL[] = [];
if (statusFilter === "paid") {
where.status = { in: [...PAID_STATUS] };
conditions.push(
inArray(WebsitePaypalTransactions.status, [...PAID_STATUS]),
);
} else if (statusFilter === "failed") {
where.status = { in: [...FAILED_STATUS] };
conditions.push(
inArray(WebsitePaypalTransactions.status, [...FAILED_STATUS]),
);
} else if (statusFilter === "pending") {
where.status = { in: [...PENDING_STATUS] };
conditions.push(
inArray(WebsitePaypalTransactions.status, [...PENDING_STATUS]),
);
}
if (parsed.search.trim()) {
@@ -72,55 +80,67 @@ export default async function AdminTransactions({
const asId = Number(q);
let userIds: number[] = [];
try {
const users = await prisma.user.findMany({
where: { username: { contains: q } },
select: { id: true },
take: 50,
});
const users = await db
.select({ id: User.id })
.from(User)
.where(like(User.username, `%${q}%`))
.limit(50);
userIds = users.map((u) => u.id);
} catch {
userIds = [];
}
where.AND = [
...(where.status ? [{ status: where.status }] : []),
{
OR: [
{ transactionId: { contains: q } },
{ description: { contains: q } },
...(Number.isFinite(asId) && asId > 0 ? [{ userId: asId }] : []),
...(userIds.length ? [{ userId: { in: userIds } }] : []),
],
},
];
delete where.status;
conditions.push(
or(
like(WebsitePaypalTransactions.transactionId, `%${q}%`),
like(WebsitePaypalTransactions.description, `%${q}%`),
...(Number.isFinite(asId) && asId > 0
? [eq(WebsitePaypalTransactions.userId, asId)]
: []),
...(userIds.length
? [inArray(WebsitePaypalTransactions.userId, userIds)]
: []),
)!,
);
}
const where = conditions.length > 0 ? and(...conditions) : undefined;
let total = 0;
try {
total = await prisma.websitePaypalTransactions.count({ where });
const [totalRow] = await db
.select({ total: count() })
.from(WebsitePaypalTransactions)
.where(where);
total = Number(totalRow?.total ?? 0);
} catch {
total = 0;
}
const pagination = calcPagination(total, parsed.page, parsed.perPage);
const sortKey = parsed.sort ?? "id";
const baseOrder = SORT_MAP[sortKey] ?? { id: "desc" as const };
const orderField = Object.keys(baseOrder)[0] as keyof typeof baseOrder;
const orderBy = {
[orderField]: parsed.order,
} as any;
const orderCol =
parsed.sort === "amount"
? WebsitePaypalTransactions.amount
: parsed.sort === "date"
? WebsitePaypalTransactions.createdAt
: parsed.sort === "status"
? WebsitePaypalTransactions.status
: parsed.sort === "package"
? WebsitePaypalTransactions.description
: parsed.sort === "payer"
? WebsitePaypalTransactions.userId
: WebsitePaypalTransactions.id;
const orderBy = parsed.order === "asc" ? asc(orderCol) : desc(orderCol);
let transactions: Awaited<
ReturnType<typeof prisma.websitePaypalTransactions.findMany>
> = [];
let transactions: (typeof WebsitePaypalTransactions.$inferSelect)[] = [];
try {
transactions = await prisma.websitePaypalTransactions.findMany({
where,
orderBy,
skip: pagination.offset,
take: pagination.perPage,
});
transactions = await db
.select()
.from(WebsitePaypalTransactions)
.where(where)
.orderBy(orderBy)
.limit(pagination.perPage)
.offset(pagination.offset);
} catch {
transactions = [];
}
@@ -129,10 +149,10 @@ export default async function AdminTransactions({
let names = new Map<number, string>();
if (userIds.length > 0) {
try {
const users = await prisma.user.findMany({
where: { id: { in: userIds } },
select: { id: true, username: true },
});
const users = await db
.select({ id: User.id, username: User.username })
.from(User)
.where(inArray(User.id, userIds));
names = new Map(users.map((u) => [u.id, u.username]));
} catch {
names = new Map();