namespace BlueLaminate.EFCore.Entities;
///
/// One physical CS2 item, identified by its fingerprint
/// (Skin + FloatValue + PaintSeed + StatTrak + Souvenir) rather than its Steam
/// asset id, which changes on every trade. Decoupled from Steam inventories on
/// purpose: an instance exists from market observation alone, and the optional
/// bridge ties it to a SteamUser only once we
/// crawl inventories.
///
/// Duping note: a duplicated item is a byte-for-byte copy with an identical
/// fingerprint, so a fingerprint is NOT guaranteed unique to one physical item.
/// We treat the fingerprint as the item, and flag
/// when the same fingerprint is seen live under two or more different asset ids
/// at once (see the sweep's dupe detection).
///
public class SkinInstance
{
public int Id { get; set; }
public int SkinId { get; set; }
public Skin Skin { get; set; } = null!;
// Nullable: market observation gives a float but not a derived wear bucket.
// Condition can be backfilled later from the float without blocking ingest.
public int? ConditionId { get; set; }
public SkinCondition? Condition { get; set; }
// The fingerprint. FloatValue is stored at full precision (see config) so
// that exact-match dupe detection isn't fooled by rounding. An instance is
// only created for items that have a float + paint seed (skins), so both are
// non-null here even though some listings (e.g. vanilla knives) lack them.
public decimal FloatValue { get; set; }
public int PaintSeed { get; set; }
public bool StatTrak { get; set; }
public bool Souvenir { get; set; }
public DateTimeOffset FirstSeenAt { get; set; }
public DateTimeOffset LastSeenAt { get; set; }
///
/// True once this fingerprint was observed live under 2+ distinct asset ids
/// simultaneously — the signature of duplication.
///
public bool SuspectedDupe { get; set; }
/// When the dupe condition was first detected. Null until then.
public DateTimeOffset? DupeFirstSeenAt { get; set; }
/// Every market listing observed for this physical item over time.
public ICollection
Listings { get; set; } = new List();
public ICollection InventoryItems { get; set; } = new List();
}