You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

45 lines
1.7 KiB

import { dbGlobal } from "drizzle-pkg/lib/db";
import { users } from "drizzle-pkg/lib/schema/auth";
import { posts, timelineEvents } from "drizzle-pkg/lib/schema/content";
import { rssFeeds } from "drizzle-pkg/lib/schema/rss";
import { desc, sql } from "drizzle-orm";
import { requireAdmin } from "#server/utils/admin-guard";
import { normalizePublicListPage } from "#server/utils/public-pagination";
export default defineWrappedResponseHandler(async (event) => {
await requireAdmin(event);
const q = getQuery(event);
const pageSize = Math.min(Number(q.pageSize ?? q.limit ?? 50) || 50, 100);
const page = normalizePublicListPage(q.page);
const offset = Math.max(Number(q.offset ?? (page - 1) * pageSize) || 0, 0);
const [countRows, rows] = await Promise.all([
dbGlobal.select({ total: sql<number>`count(*)`.mapWith(Number) }).from(users),
dbGlobal
.select({
id: users.id,
username: users.username,
email: users.email,
role: users.role,
status: users.status,
publicSlug: users.publicSlug,
createdAt: users.createdAt,
postCount: sql<number>`(select count(*) from ${posts} where ${posts.userId} = ${users.id})`.mapWith(
Number,
),
timelineEventCount: sql<number>`(select count(*) from ${timelineEvents} where ${timelineEvents.userId} = ${users.id})`.mapWith(
Number,
),
rssFeedCount: sql<number>`(select count(*) from ${rssFeeds} where ${rssFeeds.userId} = ${users.id})`.mapWith(
Number,
),
})
.from(users)
.orderBy(desc(users.id))
.limit(pageSize)
.offset(offset),
]);
return R.success({ users: rows, total: countRows[0]?.total ?? 0, page, pageSize });
});