Add bundle backtest refact + fix whitelist

This commit is contained in:
2025-10-12 14:40:20 +07:00
parent 4543246871
commit 5acc77650f
21 changed files with 2961 additions and 628 deletions

View File

@@ -30,7 +30,19 @@ public class BundleBacktestRequestEntity
[Required]
[Column(TypeName = "text")]
public string BacktestRequestsJson { get; set; } = string.Empty;
public string UniversalConfigJson { get; set; } = string.Empty;
[Required]
[Column(TypeName = "text")]
public string DateTimeRangesJson { get; set; } = string.Empty;
[Required]
[Column(TypeName = "text")]
public string MoneyManagementVariantsJson { get; set; } = string.Empty;
[Required]
[Column(TypeName = "text")]
public string TickerVariantsJson { get; set; } = string.Empty;
[Required]
public int TotalBacktests { get; set; }

View File

@@ -190,7 +190,10 @@ public class ManagingDbContext : DbContext
entity.Property(e => e.Status)
.IsRequired()
.HasConversion<string>(); // Store enum as string
entity.Property(e => e.BacktestRequestsJson).HasColumnType("text");
entity.Property(e => e.UniversalConfigJson).HasColumnType("text");
entity.Property(e => e.DateTimeRangesJson).HasColumnType("text");
entity.Property(e => e.MoneyManagementVariantsJson).HasColumnType("text");
entity.Property(e => e.TickerVariantsJson).HasColumnType("text");
entity.Property(e => e.ErrorMessage).HasColumnType("text");
entity.Property(e => e.ProgressInfo).HasColumnType("text");
entity.Property(e => e.CurrentBacktest).HasMaxLength(500);

View File

@@ -367,7 +367,10 @@ public static class PostgreSqlMappers
CreatedAt = entity.CreatedAt,
CompletedAt = entity.CompletedAt,
Status = entity.Status,
BacktestRequestsJson = entity.BacktestRequestsJson,
UniversalConfigJson = entity.UniversalConfigJson,
DateTimeRangesJson = entity.DateTimeRangesJson,
MoneyManagementVariantsJson = entity.MoneyManagementVariantsJson,
TickerVariantsJson = entity.TickerVariantsJson,
TotalBacktests = entity.TotalBacktests,
CompletedBacktests = entity.CompletedBacktests,
FailedBacktests = entity.FailedBacktests,
@@ -406,7 +409,10 @@ public static class PostgreSqlMappers
CreatedAt = bundleRequest.CreatedAt,
CompletedAt = bundleRequest.CompletedAt,
Status = bundleRequest.Status,
BacktestRequestsJson = bundleRequest.BacktestRequestsJson,
UniversalConfigJson = bundleRequest.UniversalConfigJson,
DateTimeRangesJson = bundleRequest.DateTimeRangesJson,
MoneyManagementVariantsJson = bundleRequest.MoneyManagementVariantsJson,
TickerVariantsJson = bundleRequest.TickerVariantsJson,
TotalBacktests = bundleRequest.TotalBacktests,
CompletedBacktests = bundleRequest.CompletedBacktests,
FailedBacktests = bundleRequest.FailedBacktests,

View File

@@ -12,8 +12,8 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
{
private readonly ICacheService _cacheService;
public PostgreSqlUserRepository(ManagingDbContext context, ILogger<SqlQueryLogger> logger,
SentrySqlMonitoringService sentryMonitoringService, ICacheService cacheService)
public PostgreSqlUserRepository(ManagingDbContext context, ILogger<SqlQueryLogger> logger,
SentrySqlMonitoringService sentryMonitoringService, ICacheService cacheService)
: base(context, logger, sentryMonitoringService)
{
_cacheService = cacheService;
@@ -54,10 +54,10 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
return null;
var user = PostgreSqlMappers.Map(userEntity);
// Cache user for 5 minutes since user data doesn't change frequently
_cacheService.SaveValue(cacheKey, user, TimeSpan.FromMinutes(5));
return user;
}
finally
@@ -71,20 +71,12 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
{
return await ExecuteWithLoggingAsync(async () =>
{
// Check cache first for frequently accessed users
var cacheKey = fetchAccounts ? $"user_name_with_accounts_{name}" : $"user_name_{name}";
var cachedUser = _cacheService.GetValue<User>(cacheKey);
if (cachedUser != null)
{
return cachedUser;
}
try
{
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
User user;
if (fetchAccounts)
{
// Fetch user with accounts in a single query
@@ -99,7 +91,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
throw new InvalidOperationException($"User with name '{name}' not found");
user = PostgreSqlMappers.Map(userEntity);
// Map accounts using the existing mapper
if (userEntity.Accounts != null)
{
@@ -133,12 +125,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
user = PostgreSqlMappers.Map(userEntity);
user.Accounts = new List<Account>(); // Initialize empty list
}
// Cache user for 5 minutes since user data doesn't change frequently
// Use shorter cache time when including accounts since accounts change more frequently
var cacheTime = fetchAccounts ? TimeSpan.FromMinutes(2) : TimeSpan.FromMinutes(5);
_cacheService.SaveValue(cacheKey, user, cacheTime);
return user;
}
finally
@@ -179,10 +166,10 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
.ConfigureAwait(false);
var users = userEntities.Select(PostgreSqlMappers.Map).ToList();
// Cache all users for 10 minutes since this data changes infrequently
_cacheService.SaveValue(cacheKey, users, TimeSpan.FromMinutes(10));
return users;
}
finally
@@ -209,7 +196,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
{
// Capture old AgentName before updating for cache invalidation
oldAgentName = existingUser.AgentName;
// Update existing user
existingUser.AgentName = user.AgentName;
existingUser.AvatarUrl = user.AvatarUrl;
@@ -229,7 +216,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
// Update the user object with the database-generated ID after save
await _context.SaveChangesAsync().ConfigureAwait(false);
user.Id = userEntity.Id;
// Cache the new user
var newUserNameCacheKey = $"user_name_{user.Name}";
var newUserAgentCacheKey = $"user_agent_{user.AgentName}";
@@ -238,34 +225,34 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
{
_cacheService.SaveValue(newUserAgentCacheKey, user, TimeSpan.FromMinutes(5));
}
// Invalidate all users cache since we added a new user
_cacheService.RemoveValue("all_users");
return; // Exit early since we already saved
}
await _context.SaveChangesAsync().ConfigureAwait(false);
// Invalidate cache for updated user - handle both old and new AgentName
var nameCacheKey = $"user_name_{user.Name}";
var nameWithAccountsCacheKey = $"user_name_with_accounts_{user.Name}";
_cacheService.RemoveValue(nameCacheKey);
_cacheService.RemoveValue(nameWithAccountsCacheKey);
// Invalidate old AgentName cache if it existed
if (!string.IsNullOrEmpty(oldAgentName))
{
var oldAgentCacheKey = $"user_agent_{oldAgentName}";
_cacheService.RemoveValue(oldAgentCacheKey);
}
// Invalidate new AgentName cache if it exists
if (!string.IsNullOrEmpty(user.AgentName))
{
var newAgentCacheKey = $"user_agent_{user.AgentName}";
_cacheService.RemoveValue(newAgentCacheKey);
}
// Invalidate all users cache since we updated a user
_cacheService.RemoveValue("all_users");
}