namespace BlueLaminate.EFCore.Entities;
public class Skin
{
public int Id { get; set; }
public int WeaponId { get; set; }
public Weapon Weapon { get; set; } = null!;
/// Stable id from the CSGO-API catalogue, e.g. "skin-e757fd7191f9". The natural key.
public string Slug { get; set; } = null!;
// CSFloat/CS item indexes, sourced from the static catalogue (weapon.weapon_id
// and paint_index). Together they identify a skin on CSFloat and let market
// listings join back to this catalogue row. Nullable until a sync populates
// them, since older catalogue rows predate these columns.
public int? DefIndex { get; set; }
public int? PaintIndex { get; set; }
public string Name { get; set; } = null!;
public string Rarity { get; set; } = null!;
public string? Description { get; set; }
public string? ImageUrl { get; set; }
public bool StatTrakAvailable { get; set; }
public bool SouvenirAvailable { get; set; }
/// Every collection and container this skin originates from.
public ICollection Collections { get; set; } = new List();
// Null when the catalogue gives no wear range (e.g. vanilla knives). Callers
// must treat null as "unknown", not as a full 0.0–1.0 range.
public decimal? FloatMin { get; set; }
public decimal? FloatMax { get; set; }
// Computed in the database: float_min = 0.0 AND float_max = 1.0; null while the
// bounds are unknown. A skin with a capped float range behaves differently in
// tradeup calculations.
public bool? TrueFloat { get; private set; }
public ICollection Conditions { get; set; } = new List();
// Per-site "last swept" checkpoints for the whole-skin sweep unit — only used for
// skins with no wear bands (the per-band checkpoint lives on SkinCondition.Sweeps).
// The sweep processes never-swept (no row) / stalest skins first. See SkinSweep.
public ICollection Sweeps { get; set; } = new List();
public ICollection Instances { get; set; } = new List();
public ICollection PriceHistories { get; set; } = new List();
}