feat(announcements): add locale audience targeting and published-home news
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "Announcement"
|
||||
ADD COLUMN "targetLocales" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[];
|
||||
@@ -405,6 +405,7 @@ model Announcement {
|
||||
title String
|
||||
message String
|
||||
placement String
|
||||
targetLocales String[] @default([])
|
||||
priority Int @default(100)
|
||||
ctaLabel String?
|
||||
ctaHref String?
|
||||
|
||||
@@ -41,13 +41,18 @@ describe("announcements service", () => {
|
||||
it("queries only visible announcements in the given placement", async () => {
|
||||
mockDb.announcement.findMany.mockResolvedValue([])
|
||||
|
||||
await listActiveAnnouncements("homepage")
|
||||
await listActiveAnnouncements("homepage", new Date("2026-02-12T10:00:00.000Z"), "en")
|
||||
|
||||
expect(mockDb.announcement.findMany).toHaveBeenCalledTimes(1)
|
||||
expect(mockDb.announcement.findMany.mock.calls[0]?.[0]).toMatchObject({
|
||||
where: {
|
||||
placement: "homepage",
|
||||
isVisible: true,
|
||||
AND: [
|
||||
{
|
||||
OR: [{ targetLocales: { isEmpty: true } }, { targetLocales: { has: "en" } }],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -13,6 +13,7 @@ export type PublicAnnouncement = {
|
||||
ctaLabel: string | null
|
||||
ctaHref: string | null
|
||||
placement: string
|
||||
targetLocales: string[]
|
||||
priority: number
|
||||
}
|
||||
|
||||
@@ -50,13 +51,26 @@ export async function deleteAnnouncement(id: string) {
|
||||
export async function listActiveAnnouncements(
|
||||
placement: AnnouncementPlacement,
|
||||
now = new Date(),
|
||||
locale?: string,
|
||||
): Promise<PublicAnnouncement[]> {
|
||||
const localeFilter =
|
||||
locale && locale.length > 0
|
||||
? {
|
||||
AND: [
|
||||
{
|
||||
OR: [{ targetLocales: { isEmpty: true } }, { targetLocales: { has: locale } }],
|
||||
},
|
||||
],
|
||||
}
|
||||
: undefined
|
||||
|
||||
const announcements = await db.announcement.findMany({
|
||||
where: {
|
||||
placement,
|
||||
isVisible: true,
|
||||
OR: [{ startsAt: null }, { startsAt: { lte: now } }],
|
||||
AND: [{ OR: [{ endsAt: null }, { endsAt: { gte: now } }] }],
|
||||
...(localeFilter ?? {}),
|
||||
},
|
||||
orderBy: [{ priority: "asc" }, { createdAt: "desc" }],
|
||||
select: {
|
||||
@@ -66,6 +80,7 @@ export async function listActiveAnnouncements(
|
||||
ctaLabel: true,
|
||||
ctaHref: true,
|
||||
placement: true,
|
||||
targetLocales: true,
|
||||
priority: true,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user