corrad-af-2024/server/api/notifications/audience-preview.post.js

145 lines
3.7 KiB
JavaScript

import prisma from "~/server/utils/prisma";
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event);
// Simple validation
const audienceType = body.audienceType || 'all';
const specificUsers = body.specificUsers || '';
const userSegments = Array.isArray(body.userSegments) ? body.userSegments : [];
const userStatus = body.userStatus || '';
const registrationPeriod = body.registrationPeriod || '';
const excludeUnsubscribed = body.excludeUnsubscribed !== false;
const channels = Array.isArray(body.channels) ? body.channels : [];
let totalCount = 0;
let users = [];
// Calculate total count based on audience type
if (audienceType === 'all') {
totalCount = await prisma.user.count({
where: {
userStatus: 'active'
}
});
// Get sample users for preview
users = await prisma.user.findMany({
where: {
userStatus: 'active'
},
select: {
userID: true,
userEmail: true,
userFullName: true,
userStatus: true,
userCreatedDate: true
},
take: 100,
orderBy: {
userCreatedDate: 'desc'
}
});
}
else if (audienceType === 'specific' && specificUsers) {
const usersList = specificUsers
.split('\n')
.map(u => u.trim())
.filter(Boolean);
if (usersList.length > 0) {
users = await prisma.user.findMany({
where: {
OR: [
{ userEmail: { in: usersList } },
{ userID: { in: usersList.map(id => parseInt(id)).filter(id => !isNaN(id)) } }
]
},
select: {
userID: true,
userEmail: true,
userFullName: true,
userStatus: true,
userCreatedDate: true
}
});
totalCount = users.length;
}
}
else if (audienceType === 'segmented') {
const whereClause = {
userStatus: 'active'
};
if (userStatus) {
whereClause.userStatus = userStatus;
}
if (registrationPeriod) {
const days = getRegistrationPeriodDays(registrationPeriod);
whereClause.userCreatedDate = {
gte: new Date(Date.now() - days * 24 * 60 * 60 * 1000)
};
}
totalCount = await prisma.user.count({
where: whereClause
});
users = await prisma.user.findMany({
where: whereClause,
select: {
userID: true,
userEmail: true,
userFullName: true,
userStatus: true,
userCreatedDate: true
},
take: 100,
orderBy: {
userCreatedDate: 'desc'
}
});
}
// Format users for response
const formattedUsers = users.map(user => ({
id: user.userID,
name: user.userFullName?.trim() || 'Unknown',
email: user.userEmail,
segment: audienceType === 'specific' ? 'Specific User' :
audienceType === 'segmented' ? 'Segmented User' : 'All Users',
status: user.userStatus,
registeredAt: user.userCreatedDate
}));
return {
success: true,
data: {
users: formattedUsers,
totalCount,
previewCount: formattedUsers.length
}
};
} catch (error) {
console.error('Error previewing audience:', error);
throw createError({
statusCode: 500,
statusMessage: 'Failed to preview audience',
data: {
error: error.message
}
});
}
});
function getRegistrationPeriodDays(period) {
const periodMap = {
'last_7_days': 7,
'last_30_days': 30,
'last_90_days': 90,
'last_year': 365
};
return periodMap[period] || 30;
}