arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products
arolariu.Backend.Domain.Invoicesβ
arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products Namespaceβ
Classesβ
Product Classβ
Represents a single invoice line item (product) enriched via OCR and AI classification pipelines.
public class Product
Inheritance System.Object π‘ Product
Remarksβ
Encapsulates product name (Name), 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β
Product.Category Propertyβ
Domain classification for the product.
public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductCategory Category { get; set; }
Property Valueβ
Remarksβ
Defaults to NOT_DEFINED or OTHER when enrichment has not resolved a concrete category.
Product.DetectedAllergens Propertyβ
Detected / inferred allergens associated with this product.
public System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Allergen> DetectedAllergens { get; set; }
Property Valueβ
System.Collections.Generic.IEnumerable<Allergen>
Remarksβ
List may be empty when not yet enriched. Duplicates SHOULD be avoided by upstream enrichment logic.
Product.Metadata Propertyβ
Mutable operational metadata (editing state, completion state, soft delete flag).
public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductMetadata Metadata { get; set; }
Property Valueβ
Remarksβ
Soft-deleted products remain embedded for audit; parent invoice filters them out at presentation layers.
Product.Name Propertyβ
The name of the product as extracted from the invoice via OCR.
public string Name { get; set; }
Property Valueβ
Remarksβ
Used for display, aggregation, allergen inference heuristics and recipe matching. May be empty prior to enrichment.
Product.Price Propertyβ
Unit price expressed in the parent invoiceβs currency.
public decimal Price { get; set; }
Property Valueβ
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.
Product.ProductCode Propertyβ
Optional SKU / barcode / internal product identifier.
public string ProductCode { get; set; }
Property Valueβ
Remarksβ
Used for deterministic normalization where available. May be empty if not captured by OCR or invoice source.
Product.Quantity Propertyβ
Quantity of the product associated with the unit indicated by QuantityUnit.
public decimal Quantity { get; set; }
Property Valueβ
Remarksβ
Must be non-negative. Zero often indicates an OCR failure and SHOULD be corrected upstream.
Product.QuantityUnit Propertyβ
Unit of measure for Quantity (e.g. "kg", "ml", "pcs").
public string QuantityUnit { get; set; }
Property Valueβ
Remarksβ
Empty string denotes unspecified unit; downstream analytics may treat such entries as unit-less discrete counts.
Product.TotalPrice Propertyβ
Computed extended line total (= Quantity * Price).
public decimal TotalPrice { get; }
Property Valueβ
System.Decimal
Zero when either quantity or price not yet enriched.
Structsβ
ProductMetadata Structβ
Operational metadata flags describing mutable processing / workflow state for a product line item.
public record struct ProductMetadata : System.IEquatable<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductMetadata>
Implements System.IEquatable<ProductMetadata>
Remarksβ
Scope: These flags are owned by the parent product and persisted inline (embedded) in the invoice document.
Semantics:
IsEdited: User (or automated enrichment) has modified one or more product fields after initial ingestion.IsComplete: Product line considered finalized (sufficient data quality for analytics / export).IsSoftDeleted: Product logically removed but retained for audit; parent invoice filters these at presentation layers.
Thread-safety: Not thread-safe; modifications must occur within aggregate mutation workflow.
Propertiesβ
ProductMetadata.Confidence Propertyβ
OCR confidence score for this product line item (0.0 to 1.0).
public double Confidence { get; set; }
Property Valueβ
Remarksβ
Sourced from Document Intelligence field-level confidence. Higher values indicate more reliable extraction. Zero indicates confidence was not available or not yet computed.
ProductMetadata.IsComplete Propertyβ
Signals that required enrichment / validation steps have completed for this product.
public bool IsComplete { get; set; }
Property Valueβ
Remarksβ
Downstream analytics may exclude products where this flag is false to avoid skew.
ProductMetadata.IsEdited Propertyβ
Indicates the product has been user- or system-modified post-ingestion.
public bool IsEdited { get; set; }
Property Valueβ
Remarksβ
Used to surface UI indicators and enable differential audit logging.
ProductMetadata.IsSoftDeleted Propertyβ
Logical deletion marker (soft delete) retaining historical context.
public bool IsSoftDeleted { get; set; }
Property Valueβ
Remarksβ
Soft-deleted products remain persisted; aggregate-level queries are expected to exclude them unless explicitly overridden.
Enumsβ
ProductCategory Enumβ
Classifies individual line items for enrichment, allergen aggregation, nutritional analytics and budgeting segmentation.
public enum ProductCategory
Fieldsβ
NOT_DEFINED 0
Sentinel; item category not yet classified.
BAKED_GOODS 100
Baked goods (bread, pastries, cakes, confectionery).
GROCERIES 200
General grocery staples and uncategorized pantry items.
DAIRY 300
Dairy products (milk, cheese, yogurt, butter).
MEAT 400
Meat products (red / white raw or processed).
FISH 500
Fish and seafood products.
FRUITS 600
Fruit produce (fresh, dried or minimally processed).
VEGETABLES 700
Vegetable produce (fresh, dried or minimally processed).
BEVERAGES 800
Non-alcoholic beverages (soft drinks, juices, water, energy drinks).
ALCOHOLIC_BEVERAGES 900
Alcoholic beverages (beer, wine, spirits, mixed alcohol).
TOBACCO 1000
Tobacco products and smoking accessories.
CLEANING_SUPPLIES 1100
Cleaning and household maintenance supplies.
PERSONAL_CARE 1200
Personal hygiene and grooming products.
MEDICINE 1300
Over-the-counter or prescribed medicinal / pharmaceutical items.
OTHER 9999
Fallback when no defined category applies; minimize long-term usage.
Remarksβ
Extensibility: Maintain numeric spacing (increments of 100) so downstream analytical exports relying on ordered ranges remain stable.
Sentinel:NOT_DEFINED indicates classification pending (OCR / AI enrichment or user override has not yet supplied a definitive category). SHOULD be transient.
Domain Usage: Categories drive recipe suggestion relevance, allergen risk surfacing, basket composition insights and planned per-category spend trends.
Thread-safety: Enum is immutable and inherently thread-safe.