61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
// src/services/db/price.db.ts
|
|
import type { Logger } from 'pino';
|
|
import type { PriceHistoryData } from '../../types';
|
|
import { getPool } from './connection.db';
|
|
|
|
/**
|
|
* Repository for fetching price-related data.
|
|
*/
|
|
export const priceRepo = {
|
|
/**
|
|
* Fetches the historical price data for a given list of master item IDs.
|
|
* It retrieves the price in cents and the start date of the flyer for each item.
|
|
*
|
|
* @param masterItemIds An array of master grocery item IDs.
|
|
* @param logger The pino logger instance.
|
|
* @param limit The maximum number of records to return.
|
|
* @param offset The number of records to skip.
|
|
* @returns A promise that resolves to an array of price history data points.
|
|
*/
|
|
async getPriceHistory(
|
|
masterItemIds: number[],
|
|
logger: Logger,
|
|
limit: number = 1000,
|
|
offset: number = 0,
|
|
): Promise<PriceHistoryData[]> {
|
|
if (masterItemIds.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
const query = `
|
|
SELECT
|
|
fi.master_item_id,
|
|
fi.price_in_cents,
|
|
f.valid_from AS date
|
|
FROM public.flyer_items fi
|
|
JOIN public.flyers f ON fi.flyer_id = f.flyer_id
|
|
WHERE
|
|
fi.master_item_id = ANY($1::int[])
|
|
AND f.valid_from IS NOT NULL
|
|
AND fi.price_in_cents IS NOT NULL
|
|
ORDER BY
|
|
fi.master_item_id, f.valid_from ASC
|
|
LIMIT $2 OFFSET $3;
|
|
`;
|
|
|
|
try {
|
|
const result = await getPool().query(query, [masterItemIds, limit, offset]);
|
|
logger.debug(
|
|
{ count: result.rows.length, itemIds: masterItemIds.length, limit, offset },
|
|
'Fetched price history from database.',
|
|
);
|
|
return result.rows;
|
|
} catch (error) {
|
|
logger.error(
|
|
{ err: error, masterItemIds, limit, offset },
|
|
'Database error in getPriceHistory',
|
|
);
|
|
throw new Error('Failed to retrieve price history.');
|
|
}
|
|
},
|
|
}; |