notification implemented

This commit is contained in:
root
2026-05-25 13:12:06 -04:00
parent 33b6bb55f0
commit c8bde121fc
31 changed files with 1491 additions and 1291 deletions
+25
View File
@@ -488,3 +488,28 @@ export function updatePromotion(id: string, data: Partial<{
export function deletePromotion(id: string) {
return (prisma as any).pricingPromotion.delete({ where: { id } })
}
export async function listNotificationsPage(query: {
channel?: string
status?: string
companyId?: string
page: number
pageSize: number
}) {
const where: any = {}
if (query.channel) where.channel = query.channel
if (query.status) where.status = query.status
if (query.companyId) where.companyId = query.companyId
const [data, total] = await Promise.all([
prisma.notification.findMany({
where,
orderBy: { createdAt: 'desc' },
skip: (query.page - 1) * query.pageSize,
take: query.pageSize,
include: { company: { select: { name: true } } },
}),
prisma.notification.count({ where }),
])
return { data, total }
}
+9 -1
View File
@@ -7,7 +7,7 @@ import * as subService from '../subscriptions/subscription.service'
import { presentAdminUser } from './admin.presenter'
import {
loginSchema, forgotPasswordSchema, resetPasswordSchema, totpVerifySchema,
companiesQuerySchema, rentersQuerySchema, auditLogQuerySchema, billingQuerySchema,
companiesQuerySchema, rentersQuerySchema, auditLogQuerySchema, billingQuerySchema, notificationsQuerySchema,
invoicesQuerySchema, adminCompanyUpdateSchema, companyStatusSchema,
createAdminSchema, adminRoleSchema, adminPermissionsSchema,
homepageUpdateSchema, idParamSchema, companyIdParamSchema, billingAccountIdParamSchema, invoiceIdParamSchema,
@@ -158,6 +158,14 @@ router.get('/metrics', requireAdminAuth, requireAdminRole('FINANCE'), async (req
} catch (err) { next(err) }
})
// ─── Notifications ─────────────────────────────────────────────
router.get('/notifications', requireAdminAuth, requireAdminRole('SUPPORT'), async (req, res, next) => {
try {
ok(res, await service.listNotifications(parseQuery(notificationsQuerySchema, req)))
} catch (err) { next(err) }
})
// ─── Audit logs ────────────────────────────────────────────────
router.get('/audit-logs', requireAdminAuth, requireAdminRole('ADMIN'), async (req, res, next) => {
@@ -44,6 +44,14 @@ export const auditLogQuerySchema = z.object({
pageSize: z.coerce.number().int().min(1).max(100).default(50),
})
export const notificationsQuerySchema = z.object({
channel: z.string().optional(),
status: z.string().optional(),
companyId: z.string().optional(),
page: z.coerce.number().int().min(1).default(1),
pageSize: z.coerce.number().int().min(1).max(200).default(50),
})
export const billingQuerySchema = z.object({
q: z.string().optional(),
status: z.string().optional(),
@@ -193,6 +193,11 @@ export function getPlatformMetrics() {
return repo.getPlatformMetricCounts()
}
export async function listNotifications(query: { channel?: string; status?: string; companyId?: string; page: number; pageSize: number }) {
const { data, total } = await repo.listNotificationsPage(query)
return presenter.presentPaginated(data, total, query.page, query.pageSize)
}
export async function getAuditLogs(query: { adminId?: string; action?: string; companyId?: string; entityId?: string; page: number; pageSize: number }) {
const { data, total } = await repo.listAuditLogsPage(query)
return presenter.presentPaginated(data, total, query.page, query.pageSize)