diff --git a/apps/api/src/modules/listings/repositories/listing-repository.js b/apps/api/src/modules/listings/repositories/listing-repository.js index b7cb17a..3ab93f6 100644 --- a/apps/api/src/modules/listings/repositories/listing-repository.js +++ b/apps/api/src/modules/listings/repositories/listing-repository.js @@ -1,8 +1,11 @@ import { and, asc, count, desc, eq, ilike, inArray, or, sql } from 'drizzle-orm'; import { + conditions, inventoryItems, listings, + marketValueOverrides, + marketValuations, products, } from '../../../infrastructure/database/schema.js'; @@ -134,17 +137,31 @@ export function createListingRepository(db) { async findPublicById(listingId) { const [result] = await db - .select({ listing: listings }) + .select({ listing: listings, condition: conditions }) .from(listings) .innerJoin(inventoryItems, eq(inventoryItems.id, listings.inventoryItemId)) .innerJoin(products, eq(products.id, inventoryItems.productId)) + .innerJoin(conditions, eq(conditions.id, inventoryItems.conditionId)) .where(and( eq(listings.id, listingId), inArray(listings.status, ['AVAILABLE', 'PENDING']), eq(inventoryItems.status, 'ACTIVE'), )); - return result?.listing ?? null; + if (!result) return null; + const [override] = await db.select().from(marketValueOverrides) + .where(eq(marketValueOverrides.inventoryItemId, result.listing.inventoryItemId)) + .orderBy(desc(marketValueOverrides.createdAt)).limit(1); + const [valuation] = await db.select().from(marketValuations) + .where(eq(marketValuations.inventoryItemId, result.listing.inventoryItemId)) + .orderBy(desc(marketValuations.calculatedAt)).limit(1); + return { + ...result.listing, + conditionName: result.condition.name, + conditionCode: result.condition.code, + marketValueMinor: override?.valueMinor ?? valuation?.valueMinor ?? null, + marketValueCurrency: override?.currency ?? valuation?.currency ?? null, + }; }, async updateStatus(listingId, status) { diff --git a/apps/web/src/components/organisms/CollectibleDetail.stories.js b/apps/web/src/components/organisms/CollectibleDetail.stories.js index c1dd6ed..448fc46 100644 --- a/apps/web/src/components/organisms/CollectibleDetail.stories.js +++ b/apps/web/src/components/organisms/CollectibleDetail.stories.js @@ -7,6 +7,7 @@ export const ListingDetail = { title: 'Charizard ex #199/165', status: 'AVAILABLE', priceMinor: 11500, + marketValueMinor: 12000, condition: 'Near Mint', description: 'A clean collector copy with a clear front and back.', facts: [ diff --git a/apps/web/src/components/organisms/CollectibleDetail.vue b/apps/web/src/components/organisms/CollectibleDetail.vue index 4d95aa7..14f9e93 100644 --- a/apps/web/src/components/organisms/CollectibleDetail.vue +++ b/apps/web/src/components/organisms/CollectibleDetail.vue @@ -8,6 +8,8 @@ defineProps({ title: { type: String, required: true }, status: { type: String, default: '' }, priceMinor: { type: Number, default: null }, + marketValueMinor: { type: Number, default: null }, + marketValueCurrency: { type: String, default: 'USD' }, condition: { type: String, default: '' }, description: { type: String, default: '' }, facts: { type: Array, default: () => [] }, @@ -27,6 +29,7 @@ defineProps({
{{ description }}