pub struct CatalogWriteService { /* private fields */ }Implementations§
Source§impl CatalogWriteService
impl CatalogWriteService
pub fn new(db_pool: PgPool) -> Self
Sourcepub async fn lookup_item(
&self,
code: &str,
) -> Result<Option<ItemHit>, CatalogWriteError>
pub async fn lookup_item( &self, code: &str, ) -> Result<Option<ItemHit>, CatalogWriteError>
Resolve a scanned code (barcode OR SKU/item_code) to a sellable identity. Matches the base item
first (by barcode or item_code), then a variant (by barcode or sku). None = unknown
code. Tenant-agnostic: the lookups ride the request-dedicated scoped connection when the
composed host mounts one, so out-of-scope rows are simply not found.
pub async fn create_item_group( &self, g: NewItemGroup, ) -> Result<Uuid, CatalogWriteError>
pub async fn create_item(&self, i: NewItem) -> Result<Uuid, CatalogWriteError>
Sourcepub async fn create_uom(&self, u: NewUom) -> Result<Uuid, CatalogWriteError>
pub async fn create_uom(&self, u: NewUom) -> Result<Uuid, CatalogWriteError>
Create a Uom (leaf master) on the parent-store tree (ADR-0023). Validated create so
the guarded surface can mount Uom read-only (generic delete/patch would orphan items
that FK-point at it — council 2026-07-01). With relative_uom_id set the unit becomes
a child of that reference unit and its stored factor is derived as
parent.factor * relative_factor; without it the unit is a new tree root (factor 1).
Sourcepub async fn set_uom_relative(
&self,
uom_id: Uuid,
relative: Option<(Uuid, Decimal)>,
) -> Result<(), CatalogWriteError>
pub async fn set_uom_relative( &self, uom_id: Uuid, relative: Option<(Uuid, Decimal)>, ) -> Result<(), CatalogWriteError>
Re-parent a live unit onto a new reference unit (or detach it to become a tree root
by passing None). After the link changes, every stored factor in the affected tree
is re-derived (the unit’s own and all its descendants’). Guards:
shape (both fields together), positivity, parent existence, and the
cycle rule — a unit may never point at itself or its own descendant.
Sourcepub async fn convert_quantity(
&self,
qty: Decimal,
from_uom: Uuid,
to_uom: Uuid,
rounding: ConversionRounding,
) -> Result<Decimal, CatalogWriteError>
pub async fn convert_quantity( &self, qty: Decimal, from_uom: Uuid, to_uom: Uuid, rounding: ConversionRounding, ) -> Result<Decimal, CatalogWriteError>
Convert qty from one unit to another over the parent-store tree (ADR-0023).
Application-side math over the stored factors: qty * factor_from / factor_to,
with the rounding policy declared by the caller. Units in different trees fail
LOUDLY with a typed error naming both trees — never a silent numeric result.
Sourcepub async fn delete_uom(&self, uom_id: Uuid) -> Result<(), CatalogWriteError>
pub async fn delete_uom(&self, uom_id: Uuid) -> Result<(), CatalogWriteError>
Retire (soft-delete) a unit of measure through the validated path (UM-4).
User-created units are deletable once nothing leans on them; module-seeded
reference units (is_protected) refuse deletion with a typed error — retire
those through the status lifecycle (active -> inactive) instead. The guards,
in order: the unit must exist and be live, must not be protected, must not be
the live parent of live units, and must not be the default unit of any live
item (the orphaning hazard that keeps generic delete off the guarded surface,
ADR-005). The database-level protected-unit triggers are the backstop if a
protected row ever slips past the service check.
pub async fn create_attribute( &self, a: NewAttribute, ) -> Result<Uuid, CatalogWriteError>
pub async fn create_attribute_value( &self, v: NewAttributeValue, ) -> Result<Uuid, CatalogWriteError>
Sourcepub async fn create_item_variant(
&self,
v: NewItemVariant,
) -> Result<Uuid, CatalogWriteError>
pub async fn create_item_variant( &self, v: NewItemVariant, ) -> Result<Uuid, CatalogWriteError>
Create a variant SKU. Validates the item exists, every option maps to a known
attribute+value in the registry, then persists the variant and flips the item’s
has_variants flag. variant_label defaults to the option value labels joined “ / “.
Sourcepub async fn delete_item_variant(
&self,
variant_id: Uuid,
) -> Result<(), CatalogWriteError>
pub async fn delete_item_variant( &self, variant_id: Uuid, ) -> Result<(), CatalogWriteError>
Soft-delete a variant and keep Item.has_variants honest: if the item has no live variants
left, flip the flag back to false so the storefront picker never lies.
Sourcepub async fn transition_item_status(
&self,
item_id: Uuid,
target: CatalogStatus,
) -> Result<(), CatalogWriteError>
pub async fn transition_item_status( &self, item_id: Uuid, target: CatalogStatus, ) -> Result<(), CatalogWriteError>
Transition an Item’s lifecycle status, enforcing the CatalogStatus state machine declared
in schema/hooks/catalog.hook.yaml (active ↔ inactive, active|inactive → discontinued;
discontinued is terminal).
Sourcepub async fn create_brand(&self, b: NewBrand) -> Result<Uuid, CatalogWriteError>
pub async fn create_brand(&self, b: NewBrand) -> Result<Uuid, CatalogWriteError>
Create a Brand (leaf master). Validated create — same rationale as create_uom.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for CatalogWriteService
impl !UnwindSafe for CatalogWriteService
impl Freeze for CatalogWriteService
impl Send for CatalogWriteService
impl Sync for CatalogWriteService
impl Unpin for CatalogWriteService
impl UnsafeUnpin for CatalogWriteService
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more