45 lines
1.6 KiB
TypeScript
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 }
|
|
},
|
|
})
|