"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.campaignsService = void 0; const client_1 = require("@prisma/client"); const database_1 = require("../../../config/database"); const error_handler_1 = require("../../../middleware/error-handler"); const campaignSelect = { id: true, slug: true, title: true, description: true, emailSubject: true, emailBody: true, callToAction: true, coverPhoto: true, status: true, allowSmtpEmail: true, allowMailtoLink: true, collectUserInfo: true, showEmailCount: true, showCallCount: true, allowEmailEditing: true, allowCustomRecipients: true, showResponseWall: true, highlightCampaign: true, targetGovernmentLevels: true, createdByUserId: true, createdByUserEmail: true, createdByUserName: true, createdAt: true, updatedAt: true, _count: { select: { emails: true, responses: true, }, }, }; function generateSlug(title) { return title .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') .slice(0, 80); } async function resolveSlugCollision(slug, excludeId) { let candidate = slug; let suffix = 2; while (true) { const existing = await database_1.prisma.campaign.findUnique({ where: { slug: candidate }, select: { id: true }, }); if (!existing || (excludeId && existing.id === excludeId)) { return candidate; } candidate = `${slug}-${suffix}`; suffix++; } } exports.campaignsService = { async findAll(filters, user) { const { page, limit, search, status } = filters; const skip = (page - 1) * limit; const where = {}; if (search) { where.OR = [ { title: { contains: search, mode: 'insensitive' } }, { description: { contains: search, mode: 'insensitive' } }, ]; } if (status) where.status = status; // Non-admin users only see their own campaigns const adminRoles = [client_1.UserRole.SUPER_ADMIN, client_1.UserRole.INFLUENCE_ADMIN, client_1.UserRole.MAP_ADMIN]; if (user && !adminRoles.includes(user.role)) { where.createdByUserId = user.id; } const [campaigns, total] = await Promise.all([ database_1.prisma.campaign.findMany({ where, select: campaignSelect, skip, take: limit, orderBy: { createdAt: 'desc' }, }), database_1.prisma.campaign.count({ where }), ]); return { campaigns, pagination: { page, limit, total, totalPages: Math.ceil(total / limit), }, }; }, async findById(id) { const campaign = await database_1.prisma.campaign.findUnique({ where: { id }, select: campaignSelect, }); if (!campaign) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } return campaign; }, async findBySlug(slug) { const campaign = await database_1.prisma.campaign.findUnique({ where: { slug }, select: campaignSelect, }); if (!campaign) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } return campaign; }, async create(data, user) { const baseSlug = generateSlug(data.title); const slug = await resolveSlugCollision(baseSlug); // Look up user name from DB const dbUser = await database_1.prisma.user.findUnique({ where: { id: user.id }, select: { name: true }, }); // If highlighting this campaign, unset any other highlighted campaign if (data.highlightCampaign) { await database_1.prisma.campaign.updateMany({ where: { highlightCampaign: true }, data: { highlightCampaign: false }, }); } const campaign = await database_1.prisma.campaign.create({ data: { ...data, slug, createdByUserId: user.id, createdByUserEmail: user.email, createdByUserName: dbUser?.name ?? null, }, select: campaignSelect, }); return campaign; }, async update(id, data) { const existing = await database_1.prisma.campaign.findUnique({ where: { id } }); if (!existing) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } const updateData = { ...data }; // Regenerate slug if title changes if (data.title && data.title !== existing.title) { const baseSlug = generateSlug(data.title); updateData.slug = await resolveSlugCollision(baseSlug, id); } // If highlighting this campaign, unset any other highlighted campaign if (data.highlightCampaign) { await database_1.prisma.campaign.updateMany({ where: { highlightCampaign: true, id: { not: id } }, data: { highlightCampaign: false }, }); } const campaign = await database_1.prisma.campaign.update({ where: { id }, data: updateData, select: campaignSelect, }); return campaign; }, async findActiveCampaigns() { return database_1.prisma.campaign.findMany({ where: { status: 'ACTIVE' }, select: campaignSelect, orderBy: [ { highlightCampaign: 'desc' }, { createdAt: 'desc' }, ], }); }, async findBySlugPublic(slug) { const campaign = await database_1.prisma.campaign.findUnique({ where: { slug }, select: campaignSelect, }); if (!campaign) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } if (campaign.status !== 'ACTIVE') { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } return campaign; }, async delete(id) { const existing = await database_1.prisma.campaign.findUnique({ where: { id } }); if (!existing) { throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND'); } await database_1.prisma.campaign.delete({ where: { id } }); }, }; //# sourceMappingURL=campaigns.service.js.map