47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
// src/routes/price.routes.ts
|
|
import { Router, Request, Response, NextFunction } from 'express';
|
|
import { z } from 'zod';
|
|
import { validateRequest } from '../middleware/validation.middleware';
|
|
import { priceRepo } from '../services/db/price.db';
|
|
import { optionalNumeric } from '../utils/zodUtils';
|
|
|
|
const router = Router();
|
|
|
|
const priceHistorySchema = z.object({
|
|
body: z.object({
|
|
masterItemIds: z
|
|
.array(z.number().int().positive('Number must be greater than 0'))
|
|
.nonempty({
|
|
message: 'masterItemIds must be a non-empty array of positive integers.',
|
|
}),
|
|
limit: optionalNumeric({ default: 1000, integer: true, positive: true }),
|
|
offset: optionalNumeric({ default: 0, integer: true, nonnegative: true }),
|
|
}),
|
|
});
|
|
|
|
// Infer the type from the schema for local use, as per ADR-003.
|
|
type PriceHistoryRequest = z.infer<typeof priceHistorySchema>;
|
|
|
|
/**
|
|
* POST /api/price-history - Fetches historical price data for a given list of master item IDs.
|
|
* This endpoint retrieves price points over time for specified master grocery items.
|
|
*/
|
|
router.post('/', validateRequest(priceHistorySchema), async (req: Request, res: Response, next: NextFunction) => {
|
|
// Cast 'req' to the inferred type for full type safety.
|
|
const {
|
|
body: { masterItemIds, limit, offset },
|
|
} = req as unknown as PriceHistoryRequest;
|
|
req.log.info(
|
|
{ itemCount: masterItemIds.length, limit, offset },
|
|
'[API /price-history] Received request for historical price data.',
|
|
);
|
|
try {
|
|
const priceHistory = await priceRepo.getPriceHistory(masterItemIds, req.log, limit, offset);
|
|
res.status(200).json(priceHistory);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
export default router;
|