Fix embedded-server endpoint drift, add Recalculate All Traders button

- Shared ApiConfiguration.MapPredictalyticsEndpoints() used by both the
  standalone API and the embedded WinForms Kestrel server: the embedded
  host was missing /api/watchlist and /api/dev (empty watchlist page),
  the standalone host was missing /api/search.
- New Development menu action "Recalculate All Traders": backfills
  ResolutionOutcome from snapped outcome prices, wipes derived analytics
  (snapshots, category stats, rebuildable positions), zeroes aggregates
  and marks every trader for re-analysis. Raw trades untouched.
- Static files now served with Cache-Control: no-cache in both hosts,
  plus ?v= cache-buster on app.js/style.css (stale browser JS masked
  earlier UI fixes).
- Watchlist hardened: endpoint null-safe, real Analytics.CopytradingScore,
  Platform field; repository includes Trader.Analytics; page shows a
  visible error row instead of staying silently blank.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-10 17:58:10 +02:00
co-authored by Claude Fable 5
parent 1787422243
commit 850c47a404
8 changed files with 155 additions and 30 deletions
@@ -10,7 +10,10 @@ public class WatchlistRepository : IWatchlistRepository
public WatchlistRepository(AppDbContext db) => _db = db;
public async Task<IReadOnlyList<WatchlistEntry>> GetAllAsync(CancellationToken ct = default)
=> await _db.WatchlistEntries.Include(w => w.Trader).ToListAsync(ct);
=> await _db.WatchlistEntries
.Include(w => w.Trader)
.ThenInclude(t => t.Analytics)
.ToListAsync(ct);
public async Task<WatchlistEntry?> GetByTraderIdAsync(int traderId, CancellationToken ct = default)
=> await _db.WatchlistEntries.FirstOrDefaultAsync(w => w.TraderId == traderId, ct);