Files
perauset-e2e-mrfzphpz/packages/functions/src/functions/notifications/list-notifications.function.ts
2026-07-11 08:35:02 +02:00

45 lines
1.6 KiB
TypeScript

import { z } from 'zod'
import { pikkuFunc } from '#pikku/pikku-types.gen.js'
export const ListNotificationsInput = z.object({
limit: z.coerce.number().optional().default(50).describe('Maximum number of results'),
offset: z.coerce.number().optional().default(0).describe('Offset for pagination'),
})
export const ListNotificationsOutput = z.object({
items: z.array(z.object({
notificationId: z.string().describe('Notification ID'),
type: z.string().describe('Notification type'),
title: z.string().describe('Notification title'),
body: z.string().nullable().describe('Notification body'),
entityType: z.string().nullable().describe('Related entity type'),
entityId: z.string().nullable().describe('Related entity ID'),
readAt: z.coerce.date().nullable().describe('When the notification was read'),
createdAt: z.coerce.date().describe('When the notification was created'),
})).describe('List of notifications'),
})
export const listNotifications = pikkuFunc({
expose: true,
input: ListNotificationsInput,
output: ListNotificationsOutput,
func: async ({ kysely }, { limit: rawLimit, offset: rawOffset }, { session }) => {
const limit = rawLimit ?? 50
const offset = rawOffset ?? 0
const items = await kysely
.selectFrom('notification')
.select([
'notificationId', 'type', 'title', 'body',
'entityType', 'entityId', 'readAt', 'createdAt',
])
.where('userId', '=', session!.userId)
.orderBy('createdAt', 'desc')
.limit(limit)
.offset(offset)
.execute()
return { items }
},
})