Brings up the pull-model scraper: the .NET C2 hands skin+wear jobs to Python nodriver workers that scrape cs.money and post results back, plus the supporting Core/EFCore data model, migrations, and docker-compose orchestration. IPRoyal proxying lets workers scale horizontally with a distinct residential exit IP each: every worker process mints its own sticky session at startup, and an in-process forwarding proxy injects the gateway auth so Chromium talks only to an auth-free localhost endpoint (zero CDP). On a Cloudflare challenge a worker rotates to a fresh session/IP and re-warms. Verified end-to-end against live IPRoyal: distinct US residential exits per worker and IP rotation on demand. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
22 lines
904 B
C#
22 lines
904 B
C#
namespace BlueLaminate.EFCore.Entities;
|
|
|
|
public class SkinCondition
|
|
{
|
|
public int Id { get; set; }
|
|
public int SkinId { get; set; }
|
|
public Skin Skin { get; set; } = null!;
|
|
|
|
public string Condition { get; set; } = null!;
|
|
public decimal MinFloat { get; set; }
|
|
public decimal MaxFloat { get; set; }
|
|
|
|
// When the catalogue-driven listing sweep last fully covered this skin's wear
|
|
// band. The sweep splits each skin by wear and pages one band at a time, so this
|
|
// is the per-band checkpoint: an interrupted run resumes from never-swept/stalest
|
|
// bands rather than redoing a whole skin. Null until the first sweep reaches it.
|
|
public DateTimeOffset? ListingsSweptAt { get; set; }
|
|
|
|
public ICollection<SkinInstance> Instances { get; set; } = new List<SkinInstance>();
|
|
public ICollection<PriceHistory> PriceHistories { get; set; } = new List<PriceHistory>();
|
|
}
|