129 lines
5.4 KiB
TypeScript
129 lines
5.4 KiB
TypeScript
import { Router } from 'express'
|
|
import { z } from 'zod'
|
|
import { prisma } from '../lib/prisma'
|
|
import { requireCompanyAuth } from '../middleware/requireCompanyAuth'
|
|
import { requireTenant } from '../middleware/requireTenant'
|
|
import { requireSubscription } from '../middleware/requireSubscription'
|
|
import { requireRenterAuth } from '../middleware/requireRenterAuth'
|
|
import { NotificationType, NotificationChannel } from '@rentaldrivego/database'
|
|
|
|
const router = Router()
|
|
|
|
// ─── Company notifications ────────────────────────────────────
|
|
|
|
const companyAuth = [requireCompanyAuth, requireTenant, requireSubscription]
|
|
|
|
router.get('/company', ...companyAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const { unread } = req.query as Record<string, string>
|
|
const where: any = { companyId: req.companyId, channel: 'IN_APP' }
|
|
if (unread === 'true') where.readAt = null
|
|
const notifications = await prisma.notification.findMany({ where, orderBy: { createdAt: 'desc' }, take: 50 })
|
|
res.json({ data: notifications })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/unread-count', ...companyAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const unread = await prisma.notification.count({
|
|
where: { companyId: req.companyId, channel: 'IN_APP', readAt: null },
|
|
})
|
|
res.json({ data: { unread } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/company/:id/read', ...companyAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
await prisma.notification.updateMany({ where: { id: req.params.id, companyId: req.companyId }, data: { readAt: new Date(), status: 'READ' } })
|
|
res.json({ data: { success: true } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/company/read-all', ...companyAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
await prisma.notification.updateMany({ where: { companyId: req.companyId, readAt: null }, data: { readAt: new Date(), status: 'READ' } })
|
|
res.json({ data: { success: true } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/company/preferences', ...companyAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const prefs = await prisma.notificationPreference.findMany({ where: { employeeId: req.employee.id } })
|
|
res.json({ data: prefs })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.patch('/company/preferences', ...companyAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const body = z.array(z.object({ notificationType: z.string(), channel: z.string(), enabled: z.boolean() })).parse(req.body)
|
|
for (const pref of body) {
|
|
await prisma.notificationPreference.upsert({
|
|
where: { employeeId_notificationType_channel: { employeeId: req.employee.id, notificationType: pref.notificationType as NotificationType, channel: pref.channel as NotificationChannel } },
|
|
create: { employeeId: req.employee.id, notificationType: pref.notificationType as NotificationType, channel: pref.channel as NotificationChannel, enabled: pref.enabled },
|
|
update: { enabled: pref.enabled },
|
|
})
|
|
}
|
|
res.json({ data: { success: true } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
// ─── Renter notifications ─────────────────────────────────────
|
|
|
|
router.get('/renter', requireRenterAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const notifications = await prisma.notification.findMany({ where: { renterId: req.renterId, channel: 'IN_APP' }, orderBy: { createdAt: 'desc' }, take: 50 })
|
|
res.json({ data: notifications })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/renter/:id/read', requireRenterAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
await prisma.notification.updateMany({ where: { id: req.params.id, renterId: req.renterId }, data: { readAt: new Date(), status: 'READ' } })
|
|
res.json({ data: { success: true } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.post('/renter/read-all', requireRenterAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
await prisma.notification.updateMany({
|
|
where: { renterId: req.renterId, channel: 'IN_APP', readAt: null },
|
|
data: { readAt: new Date(), status: 'READ' },
|
|
})
|
|
res.json({ data: { success: true } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.get('/renter/preferences', requireRenterAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const prefs = await prisma.notificationPreference.findMany({ where: { renterId: req.renterId } })
|
|
res.json({ data: prefs })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
router.patch('/renter/preferences', requireRenterAuth, async (req: any, res: any, next: any) => {
|
|
try {
|
|
const body = z.array(z.object({ notificationType: z.string(), channel: z.string(), enabled: z.boolean() })).parse(req.body)
|
|
for (const pref of body) {
|
|
await prisma.notificationPreference.upsert({
|
|
where: {
|
|
renterId_notificationType_channel: {
|
|
renterId: req.renterId,
|
|
notificationType: pref.notificationType as NotificationType,
|
|
channel: pref.channel as NotificationChannel,
|
|
},
|
|
},
|
|
create: {
|
|
renterId: req.renterId,
|
|
notificationType: pref.notificationType as NotificationType,
|
|
channel: pref.channel as NotificationChannel,
|
|
enabled: pref.enabled,
|
|
},
|
|
update: { enabled: pref.enabled },
|
|
})
|
|
}
|
|
res.json({ data: { success: true } })
|
|
} catch (err) { next(err) }
|
|
})
|
|
|
|
export default router
|