Browse Source

feat(api): add paginated discover users list

Made-with: Cursor
main
npmrun 12 hours ago
parent
commit
c122206bca
  1. 8
      server/api/discover/users.get.ts
  2. 56
      server/service/discover/index.ts

8
server/api/discover/users.get.ts

@ -0,0 +1,8 @@
import { listDiscoverUsersPage } from "#server/service/discover";
export default defineWrappedResponseHandler(async (event) => {
await event.context.auth.requireUser();
const q = getQuery(event);
const payload = await listDiscoverUsersPage(q.page);
return R.success(payload);
});

56
server/service/discover/index.ts

@ -0,0 +1,56 @@
import { dbGlobal } from "drizzle-pkg/lib/db";
import { users } from "drizzle-pkg/lib/schema/auth";
import { and, asc, count, eq, isNotNull, ne } from "drizzle-orm";
import { DISCOVER_LIST_PAGE_SIZE } from "#server/constants/discover-list";
import { discoverCardAvatarUrl, discoverCardLocationLine } from "#server/utils/discover-card";
import { normalizePublicListPage } from "#server/utils/public-pagination";
const listWhere = and(
eq(users.status, "active"),
eq(users.discoverVisible, true),
isNotNull(users.publicSlug),
ne(users.publicSlug, ""),
);
export type DiscoverListItem = {
publicSlug: string;
displayName: string;
avatar: string | null;
location: string | null;
};
function mapRow(row: typeof users.$inferSelect): DiscoverListItem {
const displayName = row.nickname?.trim() || row.username;
const discoverVis = Boolean(row.discoverVisible);
const showLoc = Boolean(row.discoverShowLocation);
return {
publicSlug: row.publicSlug as string,
displayName,
avatar: discoverCardAvatarUrl(row.avatar, row.avatarVisibility),
location: discoverCardLocationLine(discoverVis, showLoc, row.discoverLocation),
};
}
export async function listDiscoverUsersPage(pageRaw: unknown) {
const page = normalizePublicListPage(pageRaw);
const pageSize = DISCOVER_LIST_PAGE_SIZE;
const offset = (page - 1) * pageSize;
const [countRows, rows] = await Promise.all([
dbGlobal.select({ total: count() }).from(users).where(listWhere),
dbGlobal
.select()
.from(users)
.where(listWhere)
.orderBy(asc(users.id))
.limit(pageSize)
.offset(offset),
]);
return {
items: rows.map(mapRow),
total: countRows[0]?.total ?? 0,
page,
pageSize,
};
}
Loading…
Cancel
Save