namespace PowderCoating.Core.Entities; /// /// Platform-level master list of powder coating products across all vendors. /// Not tenant-scoped — no BaseEntity, no CompanyId, no soft delete. /// Used as a lookup table to auto-fill inventory records without an API call. /// public class PowderCatalogItem { public int Id { get; set; } /// Vendor name — e.g. "Prismatic Powders", "Columbia Coatings". Unique index with Sku. public string VendorName { get; set; } = string.Empty; /// Vendor's product SKU. Unique per vendor. public string Sku { get; set; } = string.Empty; public string ColorName { get; set; } = string.Empty; /// Cleaned short description — boilerplate stripped at import time. public string? Description { get; set; } /// Base unit price (lowest quantity tier). public decimal UnitPrice { get; set; } /// Full price tier JSON for future quantity-break pricing support. public string? PriceTiersJson { get; set; } public string? ImageUrl { get; set; } public string? SdsUrl { get; set; } public string? TdsUrl { get; set; } public string? ApplicationGuideUrl { get; set; } public string? ProductUrl { get; set; } // ── Coating specification fields ────────────────────────────────────── /// Cure temperature in degrees Fahrenheit. public decimal? CureTemperatureF { get; set; } /// Cure hold time at cure temperature, in minutes. public int? CureTimeMinutes { get; set; } /// /// Raw cure schedule text exactly as supplied by the vendor — e.g. "10 minutes @ 400°F". /// Preserved verbatim because vendor formats vary wildly and some carry application notes /// that don't reduce to a single temp/time pair (partial cures, clear-coat steps). /// public string? CureScheduleText { get; set; } /// /// All parsed cure curves as JSON — e.g. [{"tempF":400,"minutes":10},{"tempF":350,"minutes":20}]. /// Many powders list alternate lower-temperature curves; these matter for heat-sensitive /// substrates that cannot take the standard 400°F cure, so we keep every curve, not just the /// primary one in /. /// public string? CureCurvesJson { get; set; } /// Finish type — e.g. Gloss, Matte, Satin, Metallic, Texture. public string? Finish { get; set; } /// Resin chemistry — e.g. "Polyester", "TGIC", "Epoxy", "Hybrid". Distinct from . public string? ChemistryType { get; set; } /// Recommended film build (mil thickness) as free text from the vendor — e.g. "2.0-3.0 Mils". public string? MilThickness { get; set; } /// Comma-separated color family tags — e.g. "Blue,Purple". public string? ColorFamilies { get; set; } /// Whether this product requires a clear coat to activate its effect. public bool? RequiresClearCoat { get; set; } /// Theoretical coverage in sq ft per pound. Typical 80–120. public decimal? CoverageSqFtPerLb { get; set; } /// Specific gravity from the TDS. Used to derive theoretical coverage when needed. public decimal? SpecificGravity { get; set; } /// Powder transfer efficiency percentage. Typical 60–75%. public decimal? TransferEfficiency { get; set; } // ── Catalog management ──────────────────────────────────────────────── /// /// Our internal product category — e.g. "Powder Additives" for pigments/additives that are /// sold by weight in grams and mixed into clear rather than sprayed as a standalone powder. /// Null/empty for standard powders. Derived at import from the vendor's taxonomy, NOT stored /// from their raw category list. /// public string? Category { get; set; } /// /// Provenance of this record — e.g. "Columbia Coatings API". Kept SEPARATE from /// (which holds the derived manufacturer) so we can honor a /// distributor's right-to-delete by purging every record that came from their feed, /// regardless of which manufacturer made the product. /// public string? Source { get; set; } /// /// Reformulation history as supplied by the vendor — e.g. "Formulation Change: 05/22/26". /// Not a reliable modified-date (free text, reformulations only) but a useful signal that a /// product's formula — and therefore its cure specs — may have changed. /// public string? FormulationChanges { get; set; } /// True when the vendor has discontinued this product. Kept for historical lookups. public bool IsDiscontinued { get; set; } = false; /// True when this record was contributed by a tenant label scan rather than a curated import. public bool IsUserContributed { get; set; } = false; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? UpdatedAt { get; set; } /// Timestamp of the last successful sync run for this record. public DateTime? LastSyncedAt { get; set; } }