Add seller-owned pricing observation persistence, median market valuation calculation, admin routes, contracts, validation, migration, and focused tests.
This commit is contained in:
@@ -15,5 +15,6 @@
|
||||
"./public-inventory": "./public-inventory.js",
|
||||
"./public-product": "./public-product.js",
|
||||
"./public-seller": "./public-seller.js"
|
||||
,"./pricing": "./pricing.js"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
function toIsoString(value) { return value instanceof Date ? value.toISOString() : value; }
|
||||
|
||||
export function toAdminPricingObservationDto(observation) {
|
||||
return {
|
||||
id: observation.id,
|
||||
productId: observation.productId,
|
||||
inventoryItemId: observation.inventoryItemId,
|
||||
providerId: observation.providerId,
|
||||
priceMinor: observation.priceMinor,
|
||||
currency: observation.currency,
|
||||
sourceIdentifier: observation.sourceIdentifier,
|
||||
conditionId: observation.conditionId,
|
||||
sourceUrl: observation.sourceUrl ?? null,
|
||||
qualityScore: observation.qualityScore ?? null,
|
||||
observedAt: toIsoString(observation.observedAt),
|
||||
};
|
||||
}
|
||||
|
||||
export function toAdminMarketValuationDto({ valuation, observations }) {
|
||||
return {
|
||||
id: valuation.id,
|
||||
inventoryItemId: valuation.inventoryItemId,
|
||||
valueMinor: valuation.valueMinor,
|
||||
currency: valuation.currency,
|
||||
strategy: valuation.strategy,
|
||||
confidence: valuation.confidence,
|
||||
sourceCount: valuation.sourceCount,
|
||||
calculatedAt: toIsoString(valuation.calculatedAt),
|
||||
observations: observations.map(toAdminPricingObservationDto),
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"./listing": "./listing.js",
|
||||
"./sale": "./sale.js",
|
||||
"./product": "./product.js"
|
||||
,"./pricing": "./pricing.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "^4.1.8"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const createPricingObservationSchema = z.object({
|
||||
productId: z.uuid(),
|
||||
inventoryItemId: z.uuid(),
|
||||
providerId: z.string().trim().min(1).max(100),
|
||||
priceMinor: z.int().positive(),
|
||||
currency: z.string().trim().regex(/^[A-Za-z]{3}$/).optional(),
|
||||
sourceIdentifier: z.string().trim().min(1).max(255),
|
||||
conditionId: z.uuid(),
|
||||
sourceUrl: z.string().trim().url().optional(),
|
||||
qualityScore: z.int().min(0).max(100).optional(),
|
||||
}).strict();
|
||||
Reference in New Issue
Block a user