Files
EpicNext-Cms/src/lib/admin-list.ts
T
openhands 56061e41d4
CI / check (push) Failing after 12s
CI / deploy (push) Skipped
CI / release (push) Skipped
refactor: replace Prisma ORM runtime with Drizzle ORM facade
- Replace Prisma client runtime with Drizzle ORM (zero Prisma engine/query engine in production)
- Add Prisma-compatible facade (@/lib/prisma-facade.ts) backed by Drizzle for backwards compatibility
- Runtime queries route through Drizzle ORM; @prisma/client is now devDependency (types only)
- Remove @prisma/adapter-mariadb dependency; delete prisma-pool.ts and types/prisma.ts
- New Drizzle schema layer: src/db/schema.ts (176 tables) and src/lib/db.ts (connection)
- Update README documenting the dual-layer ORM architecture
- Restore src/generated/ gitignore (build artifact for local type generation)
- 0 TypeScript errors, 583 tests passing

The facade intentionally uses `any` types to match the Prisma Client API surface,
allowing existing code to run unmodified while routing queries through Drizzle at runtime.
2026-07-31 14:11:03 +02:00

74 lines
1.9 KiB
TypeScript

import { redirect } from "next/navigation";
import { calcPagination, parseListParams } from "./admin-helpers";
import { canAccess, getAdminContext, type PermissionSet } from "./permissions";
interface AdminListConfig<TRow> {
/** Permission slug required to view this page */
permission: string;
/** Default items per page. Default: 20 */
defaultPerPage?: number;
/**
* Runs the actual data query (Drizzle). Receives parsed list params and
* returns the rows + total count for the current page.
*/
fetch: (args: {
search: string;
page: number;
perPage: number;
rawParams: Record<string, string>;
}) => Promise<{ rows: TRow[]; total: number }>;
}
interface AdminListResult<TRow> {
rows: TRow[];
total: number;
page: number;
perPage: number;
lastPage: number;
locale: string;
permissions: PermissionSet;
rank: number;
}
/**
* Generic admin list data fetcher.
* Centralizes the common pattern: auth check, param parsing, pagination and
* row mapping. The caller supplies a Drizzle query via `config.fetch`.
*/
export async function fetchAdminList<TRow>(
config: AdminListConfig<TRow>,
paramsPromise: Promise<{ locale: string }>,
searchParamsPromise: Promise<Record<string, string>>,
): Promise<AdminListResult<TRow>> {
const { locale } = await paramsPromise;
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, config.permission, session.user.rank)) {
redirect("/admin");
}
const rawParams = await searchParamsPromise;
const sp = new URLSearchParams(rawParams);
const parsed = parseListParams(sp);
const perPage = config.defaultPerPage
? Number(rawParams.perPage) || config.defaultPerPage
: parsed.perPage;
const { rows, total } = await config.fetch({
search: parsed.search,
page: parsed.page,
perPage,
rawParams,
});
const pagination = calcPagination(total, parsed.page, perPage);
return {
rows,
...pagination,
locale,
permissions,
rank: session.user.rank,
};
}