From d227d24ca8f7fe716e13aae0f65ff21acea650bb Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 5 Jul 2026 14:59:39 +0200 Subject: [PATCH] Phase 6 (Stufe 5): Default-Provider auf MySQL + Readback-Verifikation - appsettings.json: Database:Provider = "MySql" (voller Umstieg). - ConfigMigrator.VerifyMySql + CLI --verify-mysql: liest Accounts, Settings, Trader, Markets aus MySQL zurueck. - Verifiziert: 3 Accounts, 3 Settings, 32 Trader (23 aktiv), 2344 Markets; Werte/AssignedAccountIds stimmen mit Exporten ueberein. Co-Authored-By: Claude Opus 4.8 --- Program.cs | 26 +++++++++++++++++++++ appsettings.json | 2 +- services/ConfigMigrator.cs | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/Program.cs b/Program.cs index e26fda6..87ee0c7 100644 --- a/Program.cs +++ b/Program.cs @@ -41,6 +41,13 @@ internal static class Program return; } + // Readback-Verifikation der migrierten Config aus MySQL. Kein UI-Start. + if (args.Length > 0 && string.Equals(args[0], "--verify-mysql", StringComparison.OrdinalIgnoreCase)) + { + RunVerifyMySql(); + return; + } + ApplicationConfiguration.Initialize(); var modules = new System.Collections.Generic.List @@ -268,4 +275,23 @@ internal static class Program Services.ConfigMigrator.RunFromJson(folder, mySql); } + + private static void RunVerifyMySql() + { + var config = new Microsoft.Extensions.Configuration.ConfigurationBuilder() + .SetBasePath(System.IO.Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: true) + .AddJsonFile("appsettings.Local.json", optional: true) + .AddEnvironmentVariables() + .Build(); + + var mySql = config["Database:MySqlConnectionString"] ?? string.Empty; + if (string.IsNullOrWhiteSpace(mySql)) + { + Console.WriteLine("FEHLER: Database:MySqlConnectionString fehlt (appsettings.Local.json)."); + return; + } + + Services.ConfigMigrator.VerifyMySql(mySql); + } } diff --git a/appsettings.json b/appsettings.json index 0de48a5..0e79295 100644 --- a/appsettings.json +++ b/appsettings.json @@ -1,6 +1,6 @@ { "Database": { - "Provider": "Mongo", + "Provider": "MySql", "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "PolyTraderDB" } diff --git a/services/ConfigMigrator.cs b/services/ConfigMigrator.cs index e2e0816..035508e 100644 --- a/services/ConfigMigrator.cs +++ b/services/ConfigMigrator.cs @@ -213,6 +213,52 @@ namespace PolyTraderSharp.Services Console.WriteLine("=== Migration abgeschlossen ==="); } + /// + /// Liest die migrierte Config aus MySQL (EF-Repos) zurueck und gibt eine Zusammenfassung + /// aus. Verifiziert Stufe 5, bevor Mongo entfernt wird. + /// + public static void VerifyMySql(string mySqlConnection) + { + Console.WriteLine("=== Verifikation MySQL (EF-Repos) ==="); + + var target = new ServiceCollection() + .AddDbContextFactory(o => o.UseMySql(mySqlConnection, ServerVersion.AutoDetect(mySqlConnection))) + .AddDbContextFactory(o => o.UseMySql(mySqlConnection, ServerVersion.AutoDetect(mySqlConnection))) + .BuildServiceProvider(); + + var coreFactory = target.GetRequiredService>(); + var ctFactory = target.GetRequiredService>(); + + IAccountRepository accRepo = new EfAccountRepository(coreFactory); + IMarketRepository mktRepo = new EfMarketRepository(coreFactory); + ITrackedTraderRepository trdRepo = new EfTrackedTraderRepository(ctFactory); + ICopyTradingAccountSettingsRepository setRepo = new EfCopyTradingAccountSettingsRepository(ctFactory); + + var accounts = accRepo.GetAll(); + Console.WriteLine($"Accounts: {accounts.Count}"); + foreach (var a in accounts.OrderBy(a => a.AccountId)) + Console.WriteLine($" #{a.AccountId} {a.Name} | Demo={a.IsDemo} Active={a.IsActive} | Wallet={Short(a.WalletAddress)} | Bal={a.TotalBalance}"); + + var settings = setRepo.GetAll(); + Console.WriteLine($"Copytrading-Settings: {settings.Count}"); + foreach (var s in settings.OrderBy(s => s.AccountId)) + Console.WriteLine($" #{s.AccountId} PerMarket={s.PerMarketLimit} PerMaster={s.PerMasterLimit} MaxBuy={s.MaxBuyPrice} PreRedeem={s.PreRedeemLimit}"); + + var traders = trdRepo.GetAll(); + Console.WriteLine($"Master-Trader: {traders.Count}"); + int active = traders.Count(t => t.IsActive); + Console.WriteLine($" davon aktiv: {active}"); + foreach (var t in traders.OrderBy(t => t.Id).Take(5)) + Console.WriteLine($" #{t.Id} {t.DisplayName} [{t.Category}] Accounts=[{string.Join(",", t.AssignedAccountIds.OrderBy(x => x))}] Trades={t.TotalTrades}"); + if (traders.Count > 5) Console.WriteLine($" … (+{traders.Count - 5} weitere)"); + + Console.WriteLine($"Markets (aktiv): {mktRepo.GetActive().Count}"); + Console.WriteLine("=== Verifikation abgeschlossen ==="); + } + + private static string Short(string s) => + string.IsNullOrEmpty(s) || s.Length <= 12 ? s : $"{s[..6]}…{s[^4..]}"; + // --- JSON-Helfer (mongoexport: Dezimalwerte als Strings, null moeglich) --- private static string Str(JsonElement el, string name, string fallback = "") {