feat: add bulk pricing refresh
Quality / test (push) Canceled after 0s

This commit is contained in:
2026-09-10 00:07:29 -04:00
parent e0d231facc
commit 099ec2fe72
10 changed files with 205 additions and 11 deletions
@@ -1,6 +1,6 @@
import { toAdminInventoryItemDto } from '@pokemon-inventory/contracts/inventory';
import {
bulkArchiveInventorySchema,
bulkInventorySchema,
createInventoryItemSchema,
} from '@pokemon-inventory/validation/inventory';
@@ -67,17 +67,29 @@ export async function registerAdminInventoryRoutes(app, options) {
request.cookies[sessionCookieName],
request.headers['x-csrf-token'],
);
const result = bulkArchiveInventorySchema.safeParse(request.body);
const result = bulkInventorySchema.safeParse(request.body);
if (!result.success) {
return validationError(reply, result);
}
const inventoryItems = await inventoryItemService.archiveMany({
inventoryItemIds: result.data.inventoryItemIds,
sellerId: request.admin.sellerId,
});
const inventoryItems = result.data.action === 'ARCHIVE'
? await inventoryItemService.archiveMany({
inventoryItemIds: result.data.inventoryItemIds,
sellerId: request.admin.sellerId,
})
: await inventoryItemService.refreshPricingMany({
inventoryItemIds: result.data.inventoryItemIds,
providerId: result.data.providerId,
sellerId: request.admin.sellerId,
});
return reply.send({ data: inventoryItems.map(toAdminInventoryItemDto) });
if (result.data.action === 'ARCHIVE') {
return reply.send({ data: inventoryItems.map(toAdminInventoryItemDto) });
}
return reply.code(202).send({
data: inventoryItems.map(({ id, status, createdAt }) => ({ id, status, createdAt })),
});
});
}
@@ -5,6 +5,7 @@ export function createInventoryItemService({
conditionRepository,
inventoryItemRepository,
productRepository,
pricingService,
}) {
return {
async listBySellerId(sellerId) {
@@ -47,5 +48,25 @@ export function createInventoryItemService({
requestedItems.forEach(({ status }) => archiveInventoryItem(status));
return inventoryItemRepository.archiveByIdsForSeller(inventoryItemIds, sellerId);
},
async refreshPricingMany({ inventoryItemIds, sellerId, providerId }) {
if (!pricingService) {
throw createApplicationError('PRICING_QUEUE_UNAVAILABLE', 'Pricing refresh queue is unavailable.', 503);
}
const items = await inventoryItemRepository.listBySellerId(sellerId);
const requestedItems = items.filter(({ id }) => inventoryItemIds.includes(id));
if (requestedItems.length !== inventoryItemIds.length) {
throw createApplicationError('INVENTORY_NOT_FOUND', 'One or more inventory items were not found.', 404);
}
return Promise.all(requestedItems.map((item) => pricingService.enqueueRefresh({
sellerId,
inventoryItemId: item.id,
providerId,
productId: item.productId,
conditionId: item.conditionId,
})));
},
};
}