- Engagement scoring listener: 11 event subscriptions, weighted scoring (donation=50, subscription=40, shift=20, canvass=15, email=10, video=3), Redis sorted set leaderboard, per-contact score + last-activity tracking - Homepage stats listener: 12 subscriptions, incremental Redis counters (emails, signups, donations, responses, canvass, videos), capped recent activity lists (last 20 per type), cache invalidation on data changes - GET /api/homepage/live-stats — public real-time counters + recent activity - GET /api/observability/engagement-leaderboard — admin top-N contacts - Total: 8 listeners, 70 subscriptions across all modules Bunker Admin
31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
import { Router, Request, Response, NextFunction } from 'express';
|
|
import { homepageService } from './homepage.service';
|
|
import { homepageStats } from '../../services/event-listeners/homepage-stats.listener';
|
|
|
|
const router = Router();
|
|
|
|
// GET /api/homepage — Aggregated public homepage data (no auth)
|
|
router.get('/', async (_req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const data = await homepageService.getPublicData();
|
|
res.json(data);
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
// GET /api/homepage/live-stats — Real-time EventBus-driven counters (no auth)
|
|
router.get('/live-stats', async (_req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const counters = await homepageStats.getCounters();
|
|
const recentSignups = await homepageStats.getRecent('signups', 5);
|
|
const recentDonations = await homepageStats.getRecent('donations', 5);
|
|
const recentResponses = await homepageStats.getRecent('responses', 5);
|
|
res.json({ counters, recent: { signups: recentSignups, donations: recentDonations, responses: recentResponses } });
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
export { router as homepageRouter };
|