API audit: expose 7d/24h windows, remove broken repair-db, add API docs

- TraderDetailDto now exposes PnL7d/WinRate7d/PnL24h/WinRate24h and
  CurrentBalance — the engine has computed these all along but the API
  never delivered them.
- Removed POST /api/dev/repair-db: its raw SQL referenced non-existent
  columns/tables (Trades.Type/Payout, Traders.LastPositionsUpdatedAt,
  table "Jobs") and would have deleted ALL TraderPositions including
  pruned-history conserves. The supported repair path is the WinForms
  "Recalculate All Traders" action.
- Swagger tags for Jobs and Dev groups; full endpoint reference in
  docs/API.md (kept generic — external consumers like PolyTrader adapt
  to our API, not vice versa).
- FIXPLAN Teil E: master-selection gap analysis as generic extensions
  (profile endpoint, out-of-sample window metrics, price-band profile
  with per-band win rate, stop-loss ratio, copyability aggregates with
  category fees, correlation endpoint, martingale trait).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-12 18:34:02 +02:00
co-authored by Claude Fable 5
parent 28e112f128
commit a1fcb4ace5
6 changed files with 264 additions and 28 deletions
@@ -13,7 +13,7 @@ public static class DevEndpoints
{
public static void MapDevEndpoints(this IEndpointRouteBuilder routes)
{
var group = routes.MapGroup("/api/dev");
var group = routes.MapGroup("/api/dev").WithTags("Dev");
group.MapGet("/verify-positions/{traderId:int}", async (int traderId, AppDbContext db, IEnumerable<IPlatformProvider> providers, CancellationToken ct) =>
{
@@ -68,30 +68,11 @@ public static class DevEndpoints
});
});
group.MapPost("/repair-db", async (AppDbContext db, CancellationToken ct) =>
{
await db.Database.ExecuteSqlRawAsync(@"
-- 1. Fake PnL Trades löschen
DELETE FROM Trades WHERE Type = 4 AND Payout = 0 AND Size = 0;
-- 2. Positionen löschen, da sie durch Sync neu aufgebaut werden
DELETE FROM TraderPositions;
-- 3. Sync State von Tradern zurücksetzen (DeepResync forcieren)
UPDATE Traders SET
IsInitialImportComplete = 0,
LastTradesUpdatedAt = NULL,
LastPositionsUpdatedAt = NULL,
TotalPnl = 0,
WinRate = 0,
TotalTrades = 0,
EstimatedBankroll = 0;
-- 4. Jobs abbrechen
UPDATE Jobs SET Status = 5 WHERE Status IN (1, 2);
", ct);
return Results.Ok("DB repaired. DeepResync needed.");
});
// NOTE: a former POST /repair-db endpoint was removed here on purpose:
// its raw SQL referenced non-existent columns/tables (Trades.Type/Payout,
// Traders.LastPositionsUpdatedAt, table "Jobs") and would have deleted ALL
// TraderPositions including the pruned-history conserves. The supported
// repair path is the "Recalculate All Traders" action in the WinForms
// Development menu (EmbeddedWebServer.RunRecalculateAllTradersAsync).
}
}
@@ -11,7 +11,7 @@ public static class JobEndpoints
{
public static void MapJobEndpoints(this IEndpointRouteBuilder routes)
{
var group = routes.MapGroup("/api/jobs");
var group = routes.MapGroup("/api/jobs").WithTags("Jobs");
group.MapGet("/", async (IJobRepository repo, int skip = 0, int take = 50, CancellationToken ct = default) =>
{
@@ -41,7 +41,12 @@ public record TraderDetailDto(
int Trades30d,
decimal PnL30d,
decimal WinRate30d,
decimal PnL7d,
decimal WinRate7d,
decimal PnL24h,
decimal WinRate24h,
decimal EstimatedBankroll,
decimal CurrentBalance,
decimal ActivityScore,
decimal QualityScore,
decimal VolumeScore,
@@ -236,7 +236,9 @@ public class AnalyticsService : IAnalyticsService
return new TraderDetailDto(trader.Id, trader.Platform.ToString(), trader.PlatformUserId, trader.DisplayName,
trader.Notes, trader.Tier.ToString(), trader.Strategy.ToString(), trader.IsSuspectedBot, trader.ManualPriorityOverride,
trader.WinRate, trader.TotalPnl, trader.TotalTrades,
a?.Trades30d ?? 0, a?.PnL30d ?? 0, a?.WinRate30d ?? 0, a?.EstimatedBankroll ?? 0,
a?.Trades30d ?? 0, a?.PnL30d ?? 0, a?.WinRate30d ?? 0,
a?.PnL7d ?? 0, a?.WinRate7d ?? 0, a?.PnL24h ?? 0, a?.WinRate24h ?? 0,
a?.EstimatedBankroll ?? 0, a?.CurrentBalance ?? 0,
s?.ActivityScore ?? 0, s?.QualityScore ?? 0, s?.VolumeScore ?? 0, s?.TimingScore ?? 0,
s?.CombinedScore ?? 0, a?.CopytradingScore ?? 0, a?.CopytradingQualityScore ?? 0, a?.CopytradingCopyabilityScore ?? 0, s?.Rank ?? 0, wl != null, trader.CreatedAt, trader.LastPolledAt,
trader.AiStrategySummary,