Table of Contents

Class Product

Namespace
arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products
Assembly
arolariu.Backend.Domain.Invoices.dll

Represents a single invoice line item (product) enriched via OCR and AI classification pipelines.

[Owned]
[ExcludeFromCodeCoverage]
public class Product
Inheritance
Product
Inherited Members

Remarks

Encapsulates raw OCR extracted token (RawName), a normalized semantic label (GenericName), categorical classification (Category), quantitative details (Quantity, QuantityUnit), commercial identifiers (ProductCode), pricing (Price, computed TotalPrice) and enrichment artifacts (DetectedAllergens, Metadata).

Lifecycle: Instances are owned by the containing arolariu.Backend.Domain.Invoices aggregate and are persisted as embedded documents (Cosmos owned collection). They SHOULD NOT be shared across invoice aggregates.

Classification: Category and DetectedAllergens may be progressively enriched; initial ingestion often sets Category = ProductCategory.NOT_DEFINED and an empty allergen list.

Thread-safety: Not thread-safe; mutate only within the aggregate’s modification workflow.

Properties

Category

Domain classification for the product.

[JsonPropertyOrder(2)]
public ProductCategory Category { get; set; }

Property Value

ProductCategory

Remarks

Defaults to NOT_DEFINED or OTHER when enrichment has not resolved a concrete category.

DetectedAllergens

Detected / inferred allergens associated with this product.

[JsonPropertyOrder(7)]
public IEnumerable<Allergen> DetectedAllergens { get; set; }

Property Value

IEnumerable<Allergen>

Remarks

List may be empty when not yet enriched. Duplicates SHOULD be avoided by upstream enrichment logic.

GenericName

Normalized semantic label (e.g. from “MONSTER ENERGY DRINK 500ML” to “ENERGY DRINK”).

[JsonPropertyOrder(1)]
public string GenericName { get; set; }

Property Value

string

Remarks

Used for aggregation, allergen inference heuristics and recipe matching. May be empty prior to enrichment.

Metadata

Mutable operational metadata (editing state, completion state, soft delete flag).

[JsonPropertyOrder(8)]
public ProductMetadata Metadata { get; set; }

Property Value

ProductMetadata

Remarks

Soft-deleted products remain embedded for audit; parent invoice filters them out at presentation layers.

Price

Unit price expressed in the parent invoice’s currency.

[JsonPropertyOrder(6)]
public decimal Price { get; set; }

Property Value

decimal

Remarks

Represents the effective per-unit value (post-discount if already applied upstream). Non-negative decimal. Range pricing or “per unit” expressions (e.g. “1.99 / kg”) are normalized prior to persistence; variability / ambiguity SHOULD be resolved in enrichment pipeline.

ProductCode

Optional SKU / barcode / internal product identifier.

[JsonPropertyOrder(5)]
public string ProductCode { get; set; }

Property Value

string

Remarks

Used for deterministic normalization where available. May be empty if not captured by OCR or invoice source.

Quantity

Quantity of the product associated with the unit indicated by QuantityUnit.

[JsonPropertyOrder(3)]
public decimal Quantity { get; set; }

Property Value

decimal

Remarks

Must be non-negative. Zero often indicates an OCR failure and SHOULD be corrected upstream.

QuantityUnit

Unit of measure for Quantity (e.g. "kg", "ml", "pcs").

[JsonPropertyOrder(4)]
public string QuantityUnit { get; set; }

Property Value

string

Remarks

Empty string denotes unspecified unit; downstream analytics may treat such entries as unit-less discrete counts.

RawName

Raw OCR / extracted name as it appears on the physical or digital invoice.

[JsonPropertyOrder(0)]
public string RawName { get; set; }

Property Value

string

Remarks

Preserves original casing and formatting to support traceability / future reprocessing. Normalization occurs in GenericName.

TotalPrice

Computed extended line total (= Quantity * Price).

[JsonIgnore]
public decimal TotalPrice { get; }

Property Value

decimal

Zero when either quantity or price not yet enriched.