changemaker.lite/api/dist/modules/influence/campaigns/campaigns-public.routes.js

120 lines
4.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.campaignPublicRouter = void 0;
const express_1 = require("express");
const campaigns_service_1 = require("./campaigns.service");
const database_1 = require("../../../config/database");
const redis_1 = require("../../../config/redis");
const router = (0, express_1.Router)();
exports.campaignPublicRouter = router;
// GET /api/campaigns/public — list all active campaigns (public)
router.get('/public', async (_req, res, next) => {
try {
const campaigns = await campaigns_service_1.campaignsService.findActiveCampaigns();
res.json(campaigns);
}
catch (err) {
next(err);
}
});
// GET /api/campaigns/:slug/details — public campaign data (ACTIVE only)
router.get('/:slug/details', async (req, res, next) => {
try {
const slug = req.params.slug;
const campaign = await campaigns_service_1.campaignsService.findBySlugPublic(slug);
res.json(campaign);
}
catch (err) {
next(err);
}
});
// GET /api/campaigns/:slug/related — related campaigns + upcoming shifts
router.get('/:slug/related', async (req, res, next) => {
try {
const slug = req.params.slug;
const cacheKey = `campaign:related:${slug}`;
// Check cache
try {
const cached = await redis_1.redis.get(cacheKey);
if (cached) {
res.json(JSON.parse(cached));
return;
}
}
catch { /* cache miss */ }
// Find current campaign
const campaign = await database_1.prisma.campaign.findFirst({
where: { slug, status: 'ACTIVE' },
select: { id: true, targetGovernmentLevels: true },
});
if (!campaign) {
res.json({ campaigns: [], shifts: [] });
return;
}
// Related campaigns: same gov levels, exclude current, limit 3
const relatedCampaigns = await database_1.prisma.campaign.findMany({
where: {
status: 'ACTIVE',
id: { not: campaign.id },
...(campaign.targetGovernmentLevels.length > 0 && {
targetGovernmentLevels: { hasSome: campaign.targetGovernmentLevels },
}),
},
select: {
id: true,
slug: true,
title: true,
description: true,
_count: { select: { emails: true } },
},
orderBy: { createdAt: 'desc' },
take: 3,
});
// Related shifts: upcoming, limit 3
const today = new Date();
today.setHours(0, 0, 0, 0);
const relatedShifts = await database_1.prisma.shift.findMany({
where: {
date: { gte: today },
status: 'OPEN',
},
select: {
id: true,
title: true,
date: true,
startTime: true,
location: true,
maxVolunteers: true,
_count: { select: { signups: true } },
},
orderBy: { date: 'asc' },
take: 3,
});
const result = {
campaigns: relatedCampaigns.map(c => ({
id: c.id,
slug: c.slug,
title: c.title,
description: c.description?.slice(0, 150) ?? null,
emailCount: c._count.emails,
})),
shifts: relatedShifts.map(s => ({
id: s.id,
title: s.title,
startTime: `${s.date.toISOString().split('T')[0]}T${s.startTime}:00`,
location: s.location,
currentVolunteers: s._count.signups,
maxVolunteers: s.maxVolunteers,
})),
};
try {
await redis_1.redis.setex(cacheKey, 300, JSON.stringify(result));
}
catch { /* non-critical */ }
res.json(result);
}
catch (err) {
next(err);
}
});
//# sourceMappingURL=campaigns-public.routes.js.map