commit 4577c1e9a9bea93bd50922994be3e0bf9bf4abc1
parent 8296746c59297158a32282fd06c25de72fc02ad8
Author: triesap <tyson@radroots.org>
Date: Fri, 2 Jan 2026 16:59:22 +0000
listing: model bins and `radroots-core` discounts
- Replace quantity/price vectors with primary_bin_id and bins
- Introduce RadrootsListingBin with display amount/unit and pricing fields
- Switch listing discounts to RadrootsCoreDiscount in Rust and TS bindings
- Drop generated TS imports and remove legacy quantity/discount types
Diffstat:
2 files changed, 23 insertions(+), 52 deletions(-)
diff --git a/events/bindings/ts/src/types.ts b/events/bindings/ts/src/types.ts
@@ -1,5 +1,3 @@
-import type { RadrootsCoreDecimal, RadrootsCoreDiscountValue, RadrootsCoreMoney, RadrootsCorePercent, RadrootsCoreQuantity, RadrootsCoreQuantityPrice } from "@radroots/core-bindings";
-
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type JobFeedbackStatus = "payment_required" | "processing" | "error" | "success" | "partial";
@@ -106,13 +104,13 @@ export type RadrootsListSetEventIndex = { event: RadrootsNostrEvent, metadata: R
export type RadrootsListSetEventMetadata = { id: string, author: string, published_at: number, kind: number, list_set: RadrootsListSet, };
-export type RadrootsListing = { d_tag: string, farm: RadrootsListingFarmRef, product: RadrootsListingProduct, quantities: Array<RadrootsListingQuantity>, prices: RadrootsCoreQuantityPrice[], discounts?: RadrootsListingDiscount[] | null, inventory_available?: RadrootsCoreDecimal | null, availability?: RadrootsListingAvailability | null, delivery_method?: RadrootsListingDeliveryMethod | null, location?: RadrootsListingLocation | null, images?: RadrootsListingImage[] | null, };
+export type RadrootsListing = { d_tag: string, farm: RadrootsListingFarmRef, product: RadrootsListingProduct, primary_bin_id: string, bins: Array<RadrootsListingBin>, discounts?: RadrootsCoreDiscount[] | null, inventory_available?: RadrootsCoreDecimal | null, availability?: RadrootsListingAvailability | null, delivery_method?: RadrootsListingDeliveryMethod | null, location?: RadrootsListingLocation | null, images?: RadrootsListingImage[] | null, };
export type RadrootsListingAvailability = { "kind": "window", "amount": { start?: number | null, end?: number | null, } } | { "kind": "status", "amount": { status: RadrootsListingStatus, } };
-export type RadrootsListingDeliveryMethod = { "kind": "pickup" } | { "kind": "local_delivery" } | { "kind": "shipping" } | { "kind": "other", "amount": { method: string, } };
+export type RadrootsListingBin = { bin_id: string, quantity: RadrootsCoreQuantity, price_per_canonical_unit: RadrootsCoreQuantityPrice, display_amount?: RadrootsCoreDecimal | null, display_unit?: RadrootsCoreUnit | null, display_label?: string | null, display_price?: RadrootsCoreMoney | null, display_price_unit?: RadrootsCoreUnit | null, };
-export type RadrootsListingDiscount = { "kind": "quantity", "amount": { ref_quantity: string, threshold: RadrootsCoreQuantity, value: RadrootsCoreMoney, } } | { "kind": "mass", "amount": { threshold: RadrootsCoreQuantity, value: RadrootsCoreMoney, } } | { "kind": "subtotal", "amount": { threshold: RadrootsCoreMoney, value: RadrootsCoreDiscountValue, } } | { "kind": "total", "amount": { total_min: RadrootsCoreMoney, value: RadrootsCorePercent, } };
+export type RadrootsListingDeliveryMethod = { "kind": "pickup" } | { "kind": "local_delivery" } | { "kind": "shipping" } | { "kind": "other", "amount": { method: string, } };
export type RadrootsListingEventIndex = { event: RadrootsNostrEvent, metadata: RadrootsListingEventMetadata, };
@@ -130,8 +128,6 @@ export type RadrootsListingProduct = { key: string, title: string, category: str
export type RadrootsListingProductTagKeys = readonly ["key", "title", "category", "summary", "process", "lot", "location", "profile", "year"];
-export type RadrootsListingQuantity = { value: RadrootsCoreQuantity, label?: string | null, count?: number | null, };
-
export type RadrootsListingStatus = { "kind": "active" } | { "kind": "sold" } | { "kind": "other", "amount": { value: string, } };
export type RadrootsMessage = { recipients: Array<RadrootsMessageRecipient>, content: string, reply_to?: RadrootsNostrEventPtr | null, subject?: string | null, };
diff --git a/events/src/listing.rs b/events/src/listing.rs
@@ -1,6 +1,6 @@
use radroots_core::{
- RadrootsCoreDecimal, RadrootsCoreDiscountValue, RadrootsCoreMoney, RadrootsCorePercent,
- RadrootsCoreQuantity, RadrootsCoreQuantityPrice,
+ RadrootsCoreDecimal, RadrootsCoreDiscount, RadrootsCoreMoney, RadrootsCoreQuantity,
+ RadrootsCoreQuantityPrice, RadrootsCoreUnit,
};
#[cfg(feature = "ts-rs")]
use ts_rs::TS;
@@ -84,14 +84,13 @@ pub struct RadrootsListing {
#[cfg_attr(feature = "serde", serde(default))]
pub farm: RadrootsListingFarmRef,
pub product: RadrootsListingProduct,
- pub quantities: Vec<RadrootsListingQuantity>,
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreQuantityPrice[]"))]
- pub prices: Vec<RadrootsCoreQuantityPrice>,
+ pub primary_bin_id: String,
+ pub bins: Vec<RadrootsListingBin>,
#[cfg_attr(
feature = "ts-rs",
- ts(optional, type = "RadrootsListingDiscount[] | null")
+ ts(optional, type = "RadrootsCoreDiscount[] | null")
)]
- pub discounts: Option<Vec<RadrootsListingDiscount>>,
+ pub discounts: Option<Vec<RadrootsCoreDiscount>>,
#[cfg_attr(
feature = "ts-rs",
ts(optional, type = "RadrootsCoreDecimal | null")
@@ -186,46 +185,22 @@ pub struct RadrootsListingProductTagKeys;
#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug)]
-pub struct RadrootsListingQuantity {
+pub struct RadrootsListingBin {
+ pub bin_id: String,
#[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreQuantity"))]
- pub value: RadrootsCoreQuantity,
+ pub quantity: RadrootsCoreQuantity,
+ #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreQuantityPrice"))]
+ pub price_per_canonical_unit: RadrootsCoreQuantityPrice,
+ #[cfg_attr(feature = "ts-rs", ts(optional, type = "RadrootsCoreDecimal | null"))]
+ pub display_amount: Option<RadrootsCoreDecimal>,
+ #[cfg_attr(feature = "ts-rs", ts(optional, type = "RadrootsCoreUnit | null"))]
+ pub display_unit: Option<RadrootsCoreUnit>,
#[cfg_attr(feature = "ts-rs", ts(optional, type = "string | null"))]
- pub label: Option<String>,
- #[cfg_attr(feature = "ts-rs", ts(optional, type = "number | null"))]
- pub count: Option<u32>,
-}
-
-#[cfg_attr(feature = "ts-rs", derive(TS))]
-#[cfg_attr(feature = "ts-rs", ts(export, export_to = "types.ts"))]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-#[cfg_attr(feature = "serde", serde(rename_all = "snake_case", tag = "kind", content = "amount"))]
-#[derive(Clone, Debug)]
-pub enum RadrootsListingDiscount {
- Quantity {
- ref_quantity: String,
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreQuantity"))]
- threshold: RadrootsCoreQuantity,
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreMoney"))]
- value: RadrootsCoreMoney,
- },
- Mass {
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreQuantity"))]
- threshold: RadrootsCoreQuantity,
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreMoney"))]
- value: RadrootsCoreMoney,
- },
- Subtotal {
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreMoney"))]
- threshold: RadrootsCoreMoney,
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreDiscountValue"))]
- value: RadrootsCoreDiscountValue,
- },
- Total {
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCoreMoney"))]
- total_min: RadrootsCoreMoney,
- #[cfg_attr(feature = "ts-rs", ts(type = "RadrootsCorePercent"))]
- value: RadrootsCorePercent,
- },
+ pub display_label: Option<String>,
+ #[cfg_attr(feature = "ts-rs", ts(optional, type = "RadrootsCoreMoney | null"))]
+ pub display_price: Option<RadrootsCoreMoney>,
+ #[cfg_attr(feature = "ts-rs", ts(optional, type = "RadrootsCoreUnit | null"))]
+ pub display_price_unit: Option<RadrootsCoreUnit>,
}
#[cfg_attr(feature = "ts-rs", derive(TS))]