- Add lib/db (schema, postgres.js client, enums, seed, migrations) on Drizzle - Rewrite all lib and admin action queries from Prisma to Drizzle - Keep existing table/column names so no data migration is needed - Preserve signed-cookie admin auth unchanged - Map unique-violation handling from Prisma P2002 to SQLSTATE 23505 - Swap deps, scripts, Makefile, and Dockerfile from Prisma to Drizzle
This commit is contained in:
+66
-74
@@ -1,16 +1,13 @@
|
||||
import type {
|
||||
Category,
|
||||
PortfolioAsset,
|
||||
PortfolioProject,
|
||||
PortfolioProjectViewMode,
|
||||
PortfolioSection,
|
||||
} from "@prisma/client";
|
||||
import { and, asc, desc, eq } from "drizzle-orm";
|
||||
|
||||
import { cache } from "react";
|
||||
|
||||
import { db } from "@/lib/db";
|
||||
import { category, portfolioProject } from "@/lib/db/schema";
|
||||
import type { Category, PortfolioAsset, PortfolioProject, PortfolioSection } from "@/lib/db/schema";
|
||||
import type { PortfolioProjectViewMode } from "@/lib/db/enums";
|
||||
import { getPortfolioMediaBindings } from "@/lib/media";
|
||||
import type { AppLocale } from "@/lib/locale";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
type CategoryRecord = Pick<
|
||||
Category,
|
||||
@@ -240,132 +237,127 @@ export function getLocalizedValue(
|
||||
}
|
||||
|
||||
export async function getAdminPortfolioCategories() {
|
||||
const categories = await prisma.category.findMany({
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
projects: true,
|
||||
},
|
||||
const categories = await db.query.category.findMany({
|
||||
with: {
|
||||
projects: {
|
||||
columns: { id: true },
|
||||
},
|
||||
},
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: [asc(category.sortOrder), asc(category.createdAt)],
|
||||
});
|
||||
|
||||
return categories.map((category) => ({
|
||||
...mapCategory(category),
|
||||
projectCount: category._count.projects,
|
||||
return categories.map((record) => ({
|
||||
...mapCategory(record),
|
||||
projectCount: record.projects.length,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function getActivePortfolioCategories() {
|
||||
const categories = await prisma.category.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
},
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
const categories = await db.query.category.findMany({
|
||||
where: eq(category.isActive, true),
|
||||
orderBy: [asc(category.sortOrder), asc(category.createdAt)],
|
||||
});
|
||||
|
||||
return categories.map(mapCategory);
|
||||
}
|
||||
|
||||
export async function getActivePortfolioCategoryBySlug(slug: string) {
|
||||
const category = await prisma.category.findFirst({
|
||||
where: {
|
||||
slug,
|
||||
isActive: true,
|
||||
},
|
||||
const record = await db.query.category.findFirst({
|
||||
where: and(eq(category.slug, slug), eq(category.isActive, true)),
|
||||
});
|
||||
|
||||
return category ? mapCategory(category) : null;
|
||||
return record ? mapCategory(record) : null;
|
||||
}
|
||||
|
||||
export async function getAdminPortfolioProjects(filters?: {
|
||||
categoryId?: string;
|
||||
status?: "all" | "draft" | "published";
|
||||
}) {
|
||||
const projects = await prisma.portfolioProject.findMany({
|
||||
where: {
|
||||
...(filters?.categoryId ? { categoryId: filters.categoryId } : {}),
|
||||
...(filters?.status === "draft"
|
||||
? { isPublished: false }
|
||||
: filters?.status === "published"
|
||||
? { isPublished: true }
|
||||
: {}),
|
||||
},
|
||||
include: {
|
||||
const conditions = [
|
||||
filters?.categoryId ? eq(portfolioProject.categoryId, filters.categoryId) : undefined,
|
||||
filters?.status === "draft"
|
||||
? eq(portfolioProject.isPublished, false)
|
||||
: filters?.status === "published"
|
||||
? eq(portfolioProject.isPublished, true)
|
||||
: undefined,
|
||||
].filter(Boolean);
|
||||
|
||||
const projects = await db.query.portfolioProject.findMany({
|
||||
where: conditions.length ? and(...conditions) : undefined,
|
||||
with: {
|
||||
category: true,
|
||||
sections: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (section, { asc: ascOrder }) => [ascOrder(section.sortOrder), ascOrder(section.createdAt)],
|
||||
},
|
||||
assets: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (asset, { asc: ascOrder }) => [ascOrder(asset.sortOrder), ascOrder(asset.createdAt)],
|
||||
},
|
||||
},
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "desc" }],
|
||||
orderBy: [asc(portfolioProject.sortOrder), desc(portfolioProject.createdAt)],
|
||||
});
|
||||
|
||||
return projects.map((project) => mapProject(project));
|
||||
}
|
||||
|
||||
export async function getPublishedPortfolioProjects(filters?: { categorySlug?: string }) {
|
||||
const projects = await prisma.portfolioProject.findMany({
|
||||
where: {
|
||||
isPublished: true,
|
||||
category: {
|
||||
isActive: true,
|
||||
...(filters?.categorySlug ? { slug: filters.categorySlug } : {}),
|
||||
},
|
||||
},
|
||||
include: {
|
||||
const projects = await db.query.portfolioProject.findMany({
|
||||
where: eq(portfolioProject.isPublished, true),
|
||||
with: {
|
||||
category: true,
|
||||
sections: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (section, { asc: ascOrder }) => [ascOrder(section.sortOrder), ascOrder(section.createdAt)],
|
||||
},
|
||||
assets: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (asset, { asc: ascOrder }) => [ascOrder(asset.sortOrder), ascOrder(asset.createdAt)],
|
||||
},
|
||||
},
|
||||
orderBy: [{ sortOrder: "asc" }, { publishedAt: "desc" }, { createdAt: "desc" }],
|
||||
orderBy: [
|
||||
asc(portfolioProject.sortOrder),
|
||||
desc(portfolioProject.publishedAt),
|
||||
desc(portfolioProject.createdAt),
|
||||
],
|
||||
});
|
||||
|
||||
return projects.map((project) => mapProject(project));
|
||||
return projects
|
||||
.filter(
|
||||
(project) =>
|
||||
project.category.isActive &&
|
||||
(!filters?.categorySlug || project.category.slug === filters.categorySlug),
|
||||
)
|
||||
.map((project) => mapProject(project));
|
||||
}
|
||||
|
||||
export const getPublishedPortfolioProjectBySlug = cache(async function (slug: string) {
|
||||
const project = await prisma.portfolioProject.findFirst({
|
||||
where: {
|
||||
slug,
|
||||
isPublished: true,
|
||||
category: {
|
||||
isActive: true,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
const project = await db.query.portfolioProject.findFirst({
|
||||
where: and(eq(portfolioProject.slug, slug), eq(portfolioProject.isPublished, true)),
|
||||
with: {
|
||||
category: true,
|
||||
sections: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (section, { asc: ascOrder }) => [ascOrder(section.sortOrder), ascOrder(section.createdAt)],
|
||||
},
|
||||
assets: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (asset, { asc: ascOrder }) => [ascOrder(asset.sortOrder), ascOrder(asset.createdAt)],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return project ? mapProject(project) : null;
|
||||
if (!project || !project.category.isActive) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mapProject(project);
|
||||
});
|
||||
|
||||
export async function getAdminPortfolioProjectById(id: string) {
|
||||
const project = await prisma.portfolioProject.findUnique({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
const project = await db.query.portfolioProject.findFirst({
|
||||
where: eq(portfolioProject.id, id),
|
||||
with: {
|
||||
category: true,
|
||||
sections: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (section, { asc: ascOrder }) => [ascOrder(section.sortOrder), ascOrder(section.createdAt)],
|
||||
},
|
||||
assets: {
|
||||
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
||||
orderBy: (asset, { asc: ascOrder }) => [ascOrder(asset.sortOrder), ascOrder(asset.createdAt)],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user