All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 15m54s
116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
// src/routes/personalization.routes.ts
|
|
import { Router, Request, Response, NextFunction } from 'express';
|
|
import { z } from 'zod';
|
|
import * as db from '../services/db/index.db';
|
|
import { validateRequest } from '../middleware/validation.middleware';
|
|
import { publicReadLimiter } from '../config/rateLimiters';
|
|
import { sendSuccess } from '../utils/apiResponse';
|
|
|
|
const router = Router();
|
|
|
|
// --- Zod Schemas for Personalization Routes (as per ADR-003) ---
|
|
// These routes do not expect any input, so we define an empty schema
|
|
// to maintain a consistent validation pattern across the application.
|
|
const emptySchema = z.object({});
|
|
|
|
/**
|
|
* @openapi
|
|
* /personalization/master-items:
|
|
* get:
|
|
* tags: [Personalization]
|
|
* summary: Get master items list
|
|
* description: Get the master list of all grocery items. Response is cached for 1 hour.
|
|
* responses:
|
|
* 200:
|
|
* description: List of all master grocery items
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/SuccessResponse'
|
|
*/
|
|
router.get(
|
|
'/master-items',
|
|
publicReadLimiter,
|
|
validateRequest(emptySchema),
|
|
async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
// LOGGING: Track how often this heavy DB call is actually made vs served from cache
|
|
req.log.info('Fetching master items list from database...');
|
|
|
|
// Optimization: This list changes rarely. Instruct clients to cache it for 1 hour (3600s).
|
|
res.set('Cache-Control', 'public, max-age=3600');
|
|
|
|
const masterItems = await db.personalizationRepo.getAllMasterItems(req.log);
|
|
sendSuccess(res, masterItems);
|
|
} catch (error) {
|
|
req.log.error({ error }, 'Error fetching master items in /api/personalization/master-items:');
|
|
next(error);
|
|
}
|
|
},
|
|
);
|
|
|
|
/**
|
|
* @openapi
|
|
* /personalization/dietary-restrictions:
|
|
* get:
|
|
* tags: [Personalization]
|
|
* summary: Get dietary restrictions
|
|
* description: Get the master list of all available dietary restrictions.
|
|
* responses:
|
|
* 200:
|
|
* description: List of all dietary restrictions
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/SuccessResponse'
|
|
*/
|
|
router.get(
|
|
'/dietary-restrictions',
|
|
publicReadLimiter,
|
|
validateRequest(emptySchema),
|
|
async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const restrictions = await db.personalizationRepo.getDietaryRestrictions(req.log);
|
|
sendSuccess(res, restrictions);
|
|
} catch (error) {
|
|
req.log.error(
|
|
{ error },
|
|
'Error fetching dietary restrictions in /api/personalization/dietary-restrictions:',
|
|
);
|
|
next(error);
|
|
}
|
|
},
|
|
);
|
|
|
|
/**
|
|
* @openapi
|
|
* /personalization/appliances:
|
|
* get:
|
|
* tags: [Personalization]
|
|
* summary: Get kitchen appliances
|
|
* description: Get the master list of all available kitchen appliances.
|
|
* responses:
|
|
* 200:
|
|
* description: List of all kitchen appliances
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* $ref: '#/components/schemas/SuccessResponse'
|
|
*/
|
|
router.get(
|
|
'/appliances',
|
|
publicReadLimiter,
|
|
validateRequest(emptySchema),
|
|
async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const appliances = await db.personalizationRepo.getAppliances(req.log);
|
|
sendSuccess(res, appliances);
|
|
} catch (error) {
|
|
req.log.error({ error }, 'Error fetching appliances in /api/personalization/appliances:');
|
|
next(error);
|
|
}
|
|
},
|
|
);
|
|
|
|
export default router;
|