feat(pages): add scheduled publish workflow for page management
This commit is contained in:
@@ -103,6 +103,7 @@ export const createPageInputSchema = z.object({
|
||||
content: z.string().min(1),
|
||||
seoTitle: z.string().max(180).nullable().optional(),
|
||||
seoDescription: z.string().max(320).nullable().optional(),
|
||||
scheduledPublishAt: z.date().nullable().optional(),
|
||||
})
|
||||
|
||||
export const updatePageInputSchema = z.object({
|
||||
@@ -114,6 +115,7 @@ export const updatePageInputSchema = z.object({
|
||||
content: z.string().min(1).optional(),
|
||||
seoTitle: z.string().max(180).nullable().optional(),
|
||||
seoDescription: z.string().max(320).nullable().optional(),
|
||||
scheduledPublishAt: z.date().nullable().optional(),
|
||||
})
|
||||
|
||||
export const upsertPageTranslationInputSchema = z.object({
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE "Page"
|
||||
ADD COLUMN "scheduledPublishAt" TIMESTAMP(3);
|
||||
|
||||
CREATE INDEX "Page_scheduledPublishAt_idx" ON "Page"("scheduledPublishAt");
|
||||
@@ -291,6 +291,7 @@ model Page {
|
||||
seoTitle String?
|
||||
seoDescription String?
|
||||
publishedAt DateTime?
|
||||
scheduledPublishAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
navItems NavigationItem[]
|
||||
|
||||
@@ -29,6 +29,15 @@ function resolvePublishedAt(status: string): Date | null {
|
||||
return status === "published" ? new Date() : null
|
||||
}
|
||||
|
||||
function resolvePublicPageWhere(slug?: string) {
|
||||
const now = new Date()
|
||||
|
||||
return {
|
||||
...(slug ? { slug } : {}),
|
||||
OR: [{ status: "published" }, { scheduledPublishAt: { lte: now } }],
|
||||
}
|
||||
}
|
||||
|
||||
export async function listPages(limit = 50) {
|
||||
return db.page.findMany({
|
||||
orderBy: [{ updatedAt: "desc" }],
|
||||
@@ -38,7 +47,7 @@ export async function listPages(limit = 50) {
|
||||
|
||||
export async function listPublishedPageSlugs() {
|
||||
const pages = await db.page.findMany({
|
||||
where: { status: "published" },
|
||||
where: resolvePublicPageWhere(),
|
||||
orderBy: { updatedAt: "desc" },
|
||||
select: {
|
||||
slug: true,
|
||||
@@ -57,19 +66,13 @@ export async function getPageById(id: string) {
|
||||
|
||||
export async function getPublishedPageBySlug(slug: string) {
|
||||
return db.page.findFirst({
|
||||
where: {
|
||||
slug,
|
||||
status: "published",
|
||||
},
|
||||
where: resolvePublicPageWhere(slug),
|
||||
})
|
||||
}
|
||||
|
||||
export async function getPublishedPageBySlugForLocale(slug: string, locale: string) {
|
||||
const page = await db.page.findFirst({
|
||||
where: {
|
||||
slug,
|
||||
status: "published",
|
||||
},
|
||||
where: resolvePublicPageWhere(slug),
|
||||
include: {
|
||||
translations: {
|
||||
where: {
|
||||
@@ -98,11 +101,13 @@ export async function getPublishedPageBySlugForLocale(slug: string, locale: stri
|
||||
|
||||
export async function createPage(input: unknown) {
|
||||
const payload = createPageInputSchema.parse(input)
|
||||
const isImmediatelyPublished = payload.status === "published"
|
||||
|
||||
return db.page.create({
|
||||
data: {
|
||||
...payload,
|
||||
publishedAt: resolvePublishedAt(payload.status),
|
||||
scheduledPublishAt: isImmediatelyPublished ? null : (payload.scheduledPublishAt ?? null),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -110,6 +115,7 @@ export async function createPage(input: unknown) {
|
||||
export async function updatePage(input: unknown) {
|
||||
const payload = updatePageInputSchema.parse(input)
|
||||
const { id, ...data } = payload
|
||||
const isImmediatelyPublished = data.status === "published"
|
||||
|
||||
return db.page.update({
|
||||
where: { id },
|
||||
@@ -117,6 +123,12 @@ export async function updatePage(input: unknown) {
|
||||
...data,
|
||||
publishedAt:
|
||||
data.status === undefined ? undefined : data.status === "published" ? new Date() : null,
|
||||
scheduledPublishAt:
|
||||
data.scheduledPublishAt === undefined
|
||||
? undefined
|
||||
: isImmediatelyPublished
|
||||
? null
|
||||
: data.scheduledPublishAt,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user