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
+13 -10
View File
@@ -2,11 +2,11 @@ import http from 'http'
import { Server as SocketIOServer } from 'socket.io'
import cron from 'node-cron'
import jwt from 'jsonwebtoken'
import { z } from 'zod'
import { redis } from './lib/redis'
import { prisma } from './lib/prisma'
import { assertStorageConfiguration } from './lib/storage'
import { createApp, corsOrigins } from './app'
import { sendNotification } from './services/notificationService'
import {
runTrialExpirationJob,
runPaymentPendingTimeoutJob,
@@ -24,11 +24,6 @@ const io = new SocketIOServer(server, {
cors: { origin: corsOrigins, credentials: true, methods: ['GET', 'POST'] },
})
const redisMessageSchema = z.object({
type: z.string(),
payload: z.unknown(),
})
// Authenticate socket connections via JWT before joining user rooms
io.use((socket, next) => {
const token = socket.handshake.auth?.token as string | undefined
@@ -57,9 +52,8 @@ subscriber.psubscribe('notifications:*', (err) => {
subscriber.on('pmessage', (_pattern, channel, message) => {
try {
const parsed = JSON.parse(message)
const validated = redisMessageSchema.parse(parsed)
const userId = channel.replace('notifications:', '')
io.to(`user:${userId}`).emit('notification', validated)
io.to(`user:${userId}`).emit('notification', parsed)
} catch (err) {
console.error('[Redis] Invalid notification message:', err)
}
@@ -117,8 +111,17 @@ cron.schedule('0 9 * * *', async () => {
for (const sub of subscriptions) {
const owner = sub.company.employees[0]
if (owner) {
await prisma.notification.create({
data: { type: 'SUBSCRIPTION_TRIAL_ENDING', title: 'Your trial ends soon', body: 'Your 90-day free trial ends in 3 days. Add a payment method to keep access.', companyId: sub.companyId, employeeId: owner.id, channel: 'IN_APP', status: 'DELIVERED' },
await sendNotification({
type: 'SUBSCRIPTION_TRIAL_ENDING',
companyId: sub.companyId,
employeeId: owner.id,
channels: ['IN_APP'],
templateKey: 'subscription.trial_ending',
templateVariables: {
trialEndDate: sub.trialEndAt ?? new Date(Date.now() + 3 * 24 * 60 * 60 * 1000),
},
}).catch((err) => {
console.error('[Notifications] Failed to create trial ending reminder:', err?.message ?? String(err))
})
}
}