import { Router } from 'express'; import { authenticate } from '../../middleware/auth.middleware'; import { checkSocialEnabled } from './social.middleware'; import { achievementsService } from './achievements.service'; const router = Router(); router.use(authenticate, checkSocialEnabled); /** GET /api/social/achievements — my achievements with progress */ router.get('/', async (req, res, next) => { try { const achievements = await achievementsService.listForUser(req.user!.id); res.json({ achievements }); } catch (err) { next(err); } }); /** GET /api/social/achievements/definitions — all achievement definitions */ router.get('/definitions', async (_req, res) => { res.json({ achievements: achievementsService.getDefinitions() }); }); /** GET /api/social/achievements/stats — my volunteer stats */ router.get('/stats', async (req, res, next) => { try { const stats = await achievementsService.getVolunteerStats(req.user!.id); res.json({ stats }); } catch (err) { next(err); } }); /** GET /api/social/achievements/stats/:userId — another user's stats (privacy-filtered) */ router.get('/stats/:userId', async (req, res, next) => { try { const targetUserId = req.params.userId as string; // Privacy check const privacy = await (await import('../../config/database')).prisma.privacySettings.findUnique({ where: { userId: targetUserId }, }); if (privacy?.showInFriendActivity === false && targetUserId !== req.user!.id) { return res.json({ stats: null }); } const stats = await achievementsService.getVolunteerStats(targetUserId); res.json({ stats }); } catch (err) { next(err); } }); /** GET /api/social/achievements/user/:userId — another user's achievements */ router.get('/user/:userId', async (req, res, next) => { try { const targetUserId = req.params.userId as string; // Privacy check const privacy = await (await import('../../config/database')).prisma.privacySettings.findUnique({ where: { userId: targetUserId }, }); if (privacy?.showInFriendActivity === false && targetUserId !== req.user!.id) { return res.json({ achievements: [] }); } const achievements = await achievementsService.listForUser(targetUserId); // Only return unlocked achievements for other users const filtered = targetUserId === req.user!.id ? achievements : achievements.filter((a) => a.unlocked); res.json({ achievements: filtered }); } catch (err) { next(err); } }); /** GET /api/social/achievements/leaderboard — leaderboard */ router.get('/leaderboard', async (req, res, next) => { try { const type = (req.query.type as string) || 'canvass'; if (!['canvass', 'shifts', 'campaigns'].includes(type)) { return res.status(400).json({ error: { message: 'Invalid leaderboard type' } }); } const limit = Math.min(parseInt(req.query.limit as string) || 10, 50); const leaderboard = await achievementsService.getLeaderboard(type as 'canvass' | 'shifts' | 'campaigns', limit); const myRank = await achievementsService.getUserRank(req.user!.id, type as 'canvass' | 'shifts' | 'campaigns'); res.json({ leaderboard, myRank, type }); } catch (err) { next(err); } }); export const achievementsRouter = router;