changemaker.lite/api/src/modules/homepage/homepage.routes.ts
bunker-admin 5d15b4cffa Add engagement scoring and homepage stats EventBus listeners
- 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
2026-03-31 10:21:05 -06:00

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 };