Skip to main content

gingr/dto/
retail.rs

1use std::collections::BTreeMap;
2
3#[derive(
4    Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Deserialize, serde::Serialize,
5)]
6#[serde(transparent)]
7/// Gingr retail item identifier as it appears in provider DTOs.
8pub struct ItemId(u64);
9
10impl ItemId {
11    /// Wraps an already-observed Gingr identifier without claiming anything beyond provider provenance.
12    pub const fn new(value: u64) -> Self {
13        Self(value)
14    }
15
16    /// Returns the raw Gingr item id used to link retail DTOs back to provider evidence.
17    pub const fn get(self) -> u64 {
18        self.0
19    }
20}
21
22#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
23/// Gingr retail item DTO with known fields plus quarantined unknown provider keys.
24pub struct Item {
25    /// Provider record identifier observed in the Gingr payload.
26    pub id: ItemId,
27    #[serde(default)]
28    /// Provider display label retained for operator context; NVA-specific naming rules are applied downstream.
29    pub name: Option<String>,
30    #[serde(default)]
31    /// Provider SKU/code observed for the retail item and used as retail source evidence.
32    pub sku: Option<String>,
33    #[serde(default, alias = "retail_category")]
34    /// Provider category label observed for the retail item before NVA retail taxonomy validation.
35    pub category: Option<String>,
36    #[serde(default)]
37    /// Provider active flag observed for the retail item, not an NVA-approved sellability decision.
38    pub active: Option<bool>,
39    #[serde(default)]
40    /// Provider quantity-on-hand observation for inventory workflows; reconciliation remains downstream.
41    pub quantity_on_hand: Option<u32>,
42    #[serde(flatten)]
43    /// Extra provider fields preserved for audit and future mapping without becoming validated NVA facts.
44    pub unknown: BTreeMap<String, serde_json::Value>,
45}