diff --git a/apps/api/src/modules/pricing/routes/admin-pricing-routes.js b/apps/api/src/modules/pricing/routes/admin-pricing-routes.js
index 13642b0..1732e8a 100644
--- a/apps/api/src/modules/pricing/routes/admin-pricing-routes.js
+++ b/apps/api/src/modules/pricing/routes/admin-pricing-routes.js
@@ -74,6 +74,7 @@ export async function registerAdminPricingRoutes(app, options) {
id: job.id,
status: job.status,
error: job.error ?? null,
+ valueMinor: job.valuation?.valuation?.valueMinor ?? null,
createdAt: job.createdAt,
updatedAt: job.updatedAt,
},
diff --git a/apps/web/src/pages/AdminHomePage.vue b/apps/web/src/pages/AdminHomePage.vue
index 24599a3..c76c141 100644
--- a/apps/web/src/pages/AdminHomePage.vue
+++ b/apps/web/src/pages/AdminHomePage.vue
@@ -9,7 +9,7 @@ import { createAdminListing, listAdminListings, markListingPending, publishAdmin
import { createAdminSale, listAdminSales, voidAdminSale } from '@/services/admin-sale-service.js';
import { createAdminAcquisition, listAdminAcquisitions } from '@/services/admin-acquisition-service.js';
import { getAdminDashboard } from '@/services/admin-dashboard-service.js';
-import { addAdminPricingObservation, calculateAdminValuation, overrideAdminValuation } from '@/services/admin-pricing-service.js';
+import { addAdminPricingObservation, calculateAdminValuation, enqueueAdminPricingRefresh, getAdminPricingJob, overrideAdminValuation } from '@/services/admin-pricing-service.js';
import { createAdminProviderMapping, listAdminProviderMappings } from '@/services/admin-provider-mapping-service.js';
const { principal } = useAuth();
@@ -48,6 +48,7 @@ const pricingSource = ref('');
const pricingPrice = ref('');
const overridePrice = ref('');
const overrideReason = ref('');
+const refreshStatus = ref('');
const voidReasons = ref({});
const mappingProductId = ref('');
const mappingProviderId = ref('');
@@ -183,6 +184,29 @@ async function calculatePricing() {
finally { isSaving.value = false; }
}
+async function refreshPricing() {
+ isSaving.value = true;
+ refreshStatus.value = 'Queued';
+ try {
+ const item = inventory.value.find(({ id }) => id === pricingInventoryId.value);
+ const job = await enqueueAdminPricingRefresh(item.id, { productId: item.productId, conditionId: item.conditionId }, csrfToken());
+ for (let attempt = 0; attempt < 15; attempt += 1) {
+ const status = await getAdminPricingJob(job.id);
+ refreshStatus.value = status.status;
+ if (status.status === 'COMPLETED') {
+ valuations.value = { ...valuations.value, [item.id]: { valueMinor: status.valueMinor, confidence: 'PROVIDER', sourceCount: null, stale: false } };
+ return;
+ }
+ if (status.status === 'FAILED') throw new Error(status.error ?? 'Pricing refresh failed.');
+ await new Promise((resolve) => setTimeout(resolve, 500));
+ }
+ throw new Error('Pricing refresh is taking longer than expected.');
+ } catch (requestError) {
+ error.value = requestError;
+ refreshStatus.value = 'FAILED';
+ } finally { isSaving.value = false; }
+}
+
async function overridePricing() {
isSaving.value = true;
try {
@@ -337,6 +361,7 @@ onMounted(load);
+
diff --git a/apps/web/src/services/admin-pricing-service.js b/apps/web/src/services/admin-pricing-service.js
index ca4c5af..3b21148 100644
--- a/apps/web/src/services/admin-pricing-service.js
+++ b/apps/web/src/services/admin-pricing-service.js
@@ -33,3 +33,15 @@ export function overrideAdminValuation(inventoryItemId, input, csrfToken) {
body: JSON.stringify(input),
});
}
+
+export function enqueueAdminPricingRefresh(inventoryItemId, input, csrfToken) {
+ return request(`/admin/inventory/${encodeURIComponent(inventoryItemId)}/pricing/refresh`, {
+ method: 'POST',
+ headers: { 'x-csrf-token': csrfToken },
+ body: JSON.stringify(input),
+ });
+}
+
+export function getAdminPricingJob(jobId) {
+ return request(`/admin/jobs/${encodeURIComponent(jobId)}`);
+}