91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import { Router } from 'express';
|
|
import { z } from 'zod';
|
|
import { checkSocialEnabled } from './social.middleware';
|
|
import { socialActionRateLimit } from './social.rate-limits';
|
|
import { recommendationService } from './recommendation.service';
|
|
import { friendsPaginationSchema } from './social.schemas';
|
|
|
|
const sendRecommendationSchema = z.object({
|
|
userId: z.string().cuid(),
|
|
mediaId: z.number().int().positive(),
|
|
message: z.string().max(500).optional(),
|
|
});
|
|
|
|
const router = Router();
|
|
|
|
// All recommendation routes require social to be enabled
|
|
router.use(checkSocialEnabled);
|
|
|
|
/** POST /api/social/recommendations — Send a video recommendation */
|
|
router.post('/', socialActionRateLimit, async (req, res, next) => {
|
|
try {
|
|
const input = sendRecommendationSchema.parse(req.body);
|
|
const result = await recommendationService.sendRecommendation(
|
|
req.user!.id,
|
|
input.userId,
|
|
input.mediaId,
|
|
input.message,
|
|
);
|
|
res.status(201).json(result);
|
|
} catch (err: any) {
|
|
if (err.statusCode) {
|
|
res.status(err.statusCode).json({ error: { message: err.message } });
|
|
return;
|
|
}
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
/** GET /api/social/recommendations — List received recommendations */
|
|
router.get('/', async (req, res, next) => {
|
|
try {
|
|
const { page, limit } = friendsPaginationSchema.parse(req.query);
|
|
const result = await recommendationService.listReceivedRecommendations(req.user!.id, page, limit);
|
|
res.json(result);
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
/** GET /api/social/recommendations/sent — List sent recommendations */
|
|
router.get('/sent', async (req, res, next) => {
|
|
try {
|
|
const { page, limit } = friendsPaginationSchema.parse(req.query);
|
|
const result = await recommendationService.listSentRecommendations(req.user!.id, page, limit);
|
|
res.json(result);
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
/** GET /api/social/recommendations/count — Unread count */
|
|
router.get('/count', async (req, res, next) => {
|
|
try {
|
|
const count = await recommendationService.getUnreadCount(req.user!.id);
|
|
res.json({ count });
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
/** POST /api/social/recommendations/:id/read — Mark as read */
|
|
router.post('/:id/read', async (req, res, next) => {
|
|
try {
|
|
const id = parseInt(req.params.id as string, 10);
|
|
if (isNaN(id)) {
|
|
res.status(400).json({ error: { message: 'Invalid recommendation ID' } });
|
|
return;
|
|
}
|
|
const result = await recommendationService.markRecommendationRead(req.user!.id, id);
|
|
res.json(result);
|
|
} catch (err: any) {
|
|
if (err.statusCode) {
|
|
res.status(err.statusCode).json({ error: { message: err.message } });
|
|
return;
|
|
}
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
export { router as recommendationRouter };
|