Refactor: solo SQLite, limiti auto, UI statistiche nuova
Rimosso completamente il supporto a PostgreSQL: ora tutte le statistiche e i dati persistenti usano solo SQLite, con percorso configurabile tramite DATA_PATH per Docker/volumi. Aggiunta gestione avanzata delle statistiche per prodotto, limiti consigliati calcolati automaticamente e applicabili dalla UI. Rinnovata la pagina Statistiche con tabelle aste recenti e prodotti, rimosso il supporto a grafici legacy e a "Puntate Gratuite". Migliorata la ricerca e la gestione delle aste nel browser, aggiunta diagnostica avanzata e logging dettagliato per il database. Aggiornati Dockerfile e docker-compose: l'app è ora self-contained e pronta per l'uso senza database esterni.
This commit is contained in:
@@ -37,8 +37,14 @@ namespace AutoBidder.Models
|
||||
public double MaxPrice { get; set; } = 0;
|
||||
public int MinResets { get; set; } = 0; // Numero minimo reset prima di puntare
|
||||
public int MaxResets { get; set; } = 0; // Numero massimo reset (0 = illimitati)
|
||||
|
||||
/// <summary>
|
||||
/// [OBSOLETO] Numero massimo di puntate consentite - Non più utilizzato nell'UI
|
||||
/// Mantenuto per retrocompatibilità con salvataggi JSON esistenti
|
||||
/// </summary>
|
||||
[Obsolete("MaxClicks non è più utilizzato. Usa invece la logica di limiti per prodotto.")]
|
||||
[JsonPropertyName("MaxClicks")]
|
||||
public int MaxClicks { get; set; } = 0; // Numero massimo di puntate consentite (0 = illimitato)
|
||||
public int MaxClicks { get; set; } = 0;
|
||||
|
||||
// Stato asta
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
120
Mimante/Models/ProductStatisticsRecord.cs
Normal file
120
Mimante/Models/ProductStatisticsRecord.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
namespace AutoBidder.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Record per le statistiche aggregate di un prodotto nel database
|
||||
/// </summary>
|
||||
public class ProductStatisticsRecord
|
||||
{
|
||||
public string ProductKey { get; set; } = string.Empty;
|
||||
public string ProductName { get; set; } = string.Empty;
|
||||
|
||||
// Contatori
|
||||
public int TotalAuctions { get; set; }
|
||||
public int WonAuctions { get; set; }
|
||||
public int LostAuctions { get; set; }
|
||||
|
||||
// Statistiche prezzo
|
||||
public double AvgFinalPrice { get; set; }
|
||||
public double? MinFinalPrice { get; set; }
|
||||
public double? MaxFinalPrice { get; set; }
|
||||
|
||||
// Statistiche puntate
|
||||
public double AvgBidsToWin { get; set; }
|
||||
public int? MinBidsToWin { get; set; }
|
||||
public int? MaxBidsToWin { get; set; }
|
||||
|
||||
// Statistiche reset
|
||||
public double AvgResets { get; set; }
|
||||
public int? MinResets { get; set; }
|
||||
public int? MaxResets { get; set; }
|
||||
|
||||
// Limiti consigliati (calcolati dall'algoritmo)
|
||||
public double? RecommendedMinPrice { get; set; }
|
||||
public double? RecommendedMaxPrice { get; set; }
|
||||
public int? RecommendedMinResets { get; set; }
|
||||
public int? RecommendedMaxResets { get; set; }
|
||||
public int? RecommendedMaxBids { get; set; }
|
||||
|
||||
// JSON con statistiche per fascia oraria
|
||||
public string? HourlyStatsJson { get; set; }
|
||||
|
||||
// Metadata
|
||||
public string? LastUpdated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calcola il win rate come percentuale
|
||||
/// </summary>
|
||||
public double WinRate => TotalAuctions > 0 ? (double)WonAuctions / TotalAuctions * 100 : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Risultato asta esteso con tutti i campi per analytics
|
||||
/// </summary>
|
||||
public class AuctionResultExtended
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string AuctionId { get; set; } = "";
|
||||
public string AuctionName { get; set; } = "";
|
||||
public double FinalPrice { get; set; }
|
||||
public int BidsUsed { get; set; }
|
||||
public bool Won { get; set; }
|
||||
public string Timestamp { get; set; } = "";
|
||||
public double? BuyNowPrice { get; set; }
|
||||
public double? ShippingCost { get; set; }
|
||||
public double? TotalCost { get; set; }
|
||||
public double? Savings { get; set; }
|
||||
|
||||
// Campi estesi per analytics
|
||||
public string? WinnerUsername { get; set; }
|
||||
public int? ClosedAtHour { get; set; }
|
||||
public string? ProductKey { get; set; }
|
||||
public int? TotalResets { get; set; }
|
||||
public int? WinnerBidsUsed { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Limiti consigliati per un'asta basati sulle statistiche storiche
|
||||
/// </summary>
|
||||
public class RecommendedLimits
|
||||
{
|
||||
public double MinPrice { get; set; }
|
||||
public double MaxPrice { get; set; }
|
||||
public int MinResets { get; set; }
|
||||
public int MaxResets { get; set; }
|
||||
public int MaxBids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Confidence score (0-100) - quanto sono affidabili questi limiti
|
||||
/// </summary>
|
||||
public int ConfidenceScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Numero di aste usate per calcolare i limiti
|
||||
/// </summary>
|
||||
public int SampleSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fascia oraria migliore per vincere (0-23)
|
||||
/// </summary>
|
||||
public int? BestHourToPlay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Win rate medio per questo prodotto
|
||||
/// </summary>
|
||||
public double? AverageWinRate { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statistiche per fascia oraria
|
||||
/// </summary>
|
||||
public class HourlyStats
|
||||
{
|
||||
public int Hour { get; set; }
|
||||
public int TotalAuctions { get; set; }
|
||||
public int WonAuctions { get; set; }
|
||||
public double AvgFinalPrice { get; set; }
|
||||
public double AvgBidsUsed { get; set; }
|
||||
|
||||
public double WinRate => TotalAuctions > 0 ? (double)WonAuctions / TotalAuctions * 100 : 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user