This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
export function createPricingProvider({ id, observe }) {
|
||||
if (typeof id !== 'string' || id.trim().length === 0) {
|
||||
throw new Error('Pricing provider id is required.');
|
||||
}
|
||||
|
||||
if (typeof observe !== 'function') {
|
||||
throw new TypeError('Pricing provider observe function is required.');
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
id: id.trim(),
|
||||
async observe(input) {
|
||||
const observations = await observe(input);
|
||||
if (!Array.isArray(observations)) {
|
||||
throw new Error(`Pricing provider ${id} must return an observation array.`);
|
||||
}
|
||||
return observations;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function createPricingProviderRegistry(providers = []) {
|
||||
const providerMap = new Map(providers.map((provider) => [provider.id, provider]));
|
||||
|
||||
return {
|
||||
get(providerId) {
|
||||
return providerMap.get(providerId) ?? null;
|
||||
},
|
||||
list() {
|
||||
return [...providerMap.values()];
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -53,4 +53,17 @@ export async function registerAdminPricingRoutes(app, options) {
|
||||
});
|
||||
return reply.code(201).send({ data: override });
|
||||
});
|
||||
|
||||
app.post('/inventory/:id/pricing/refresh', async (request, reply) => {
|
||||
await authorizeUnsafeRequest?.(request.cookies[sessionCookieName], request.headers['x-csrf-token']);
|
||||
const { providerId, productId, conditionId } = request.body ?? {};
|
||||
const result = await pricingService.refresh({
|
||||
sellerId: request.admin.sellerId,
|
||||
inventoryItemId: request.params.id,
|
||||
providerId,
|
||||
productId,
|
||||
conditionId,
|
||||
});
|
||||
return reply.code(200).send({ data: result });
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createPricingObservation } from '../domain/pricing-observation.js';
|
||||
import { createApplicationError } from '../../../shared/errors/application-error.js';
|
||||
|
||||
export function createPricingService({ pricingRepository }) {
|
||||
export function createPricingService({ pricingRepository, pricingProviderRegistry }) {
|
||||
return {
|
||||
async addObservation({ sellerId, ...input }) {
|
||||
const observation = createPricingObservation(input);
|
||||
@@ -31,5 +31,26 @@ export function createPricingService({ pricingRepository }) {
|
||||
if (result.status === 'NO_DATA') throw createApplicationError('PRICING_DATA_UNAVAILABLE', 'No pricing observations are available.', 404);
|
||||
return result;
|
||||
},
|
||||
|
||||
async refresh({ sellerId, inventoryItemId, providerId, productId, conditionId }) {
|
||||
const provider = pricingProviderRegistry?.get(providerId);
|
||||
if (!provider) {
|
||||
throw createApplicationError('PRICING_PROVIDER_UNAVAILABLE', 'Pricing provider is not configured.', 503);
|
||||
}
|
||||
|
||||
let providerObservations;
|
||||
try {
|
||||
providerObservations = await provider.observe({ inventoryItemId, productId, conditionId });
|
||||
} catch (error) {
|
||||
throw createApplicationError('PRICING_PROVIDER_FAILED', error.message, 502);
|
||||
}
|
||||
|
||||
const observations = [];
|
||||
for (const input of providerObservations) {
|
||||
observations.push(await this.addObservation({ sellerId, ...input, providerId: provider.id, inventoryItemId, productId, conditionId }));
|
||||
}
|
||||
|
||||
return { observations, valuation: await this.calculate({ sellerId, inventoryItemId }) };
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user