From 6b6dbd11d59c9a7d18c73ef4c680d3ee9ac27fff Mon Sep 17 00:00:00 2001 From: Sam <315859133@qq.com> Date: Thu, 5 Feb 2026 15:28:14 +0800 Subject: [PATCH] feat(risk-control): add database migrations and seed data --- .../DesignTimeRiskControlDbContextFactory.cs | 23 ++++++++ .../RiskControlDbContext.cs | 10 ++++ .../SeedData/RiskControlSeedData.cs | 57 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 Fengling.RiskControl.Infrastructure/DesignTimeRiskControlDbContextFactory.cs create mode 100644 Fengling.RiskControl.Infrastructure/SeedData/RiskControlSeedData.cs diff --git a/Fengling.RiskControl.Infrastructure/DesignTimeRiskControlDbContextFactory.cs b/Fengling.RiskControl.Infrastructure/DesignTimeRiskControlDbContextFactory.cs new file mode 100644 index 0000000..c293da8 --- /dev/null +++ b/Fengling.RiskControl.Infrastructure/DesignTimeRiskControlDbContextFactory.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Logging; + +namespace Fengling.RiskControl.Infrastructure; + +public class DesignTimeRiskControlDbContextFactory : IDesignTimeDbContextFactory +{ + private readonly ILoggerFactory _loggerFactory; + + public DesignTimeRiskControlDbContextFactory(ILoggerFactory loggerFactory) + { + _loggerFactory = loggerFactory; + } + + public RiskControlDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseNpgsql("Host=localhost;Database=RiskControl;Username=postgres;Password=postgres"); + optionsBuilder.UseLoggerFactory(_loggerFactory); + return new RiskControlDbContext(optionsBuilder.Options); + } +} diff --git a/Fengling.RiskControl.Infrastructure/RiskControlDbContext.cs b/Fengling.RiskControl.Infrastructure/RiskControlDbContext.cs index 78918a8..167f291 100644 --- a/Fengling.RiskControl.Infrastructure/RiskControlDbContext.cs +++ b/Fengling.RiskControl.Infrastructure/RiskControlDbContext.cs @@ -4,6 +4,7 @@ using Fengling.RiskControl.Domain.Aggregates.RiskRules; using Fengling.RiskControl.Domain.Aggregates.RiskScores; using Fengling.RiskControl.Domain.Aggregates.RiskAlerts; using Fengling.RiskControl.Domain.Aggregates.LotteryActivities; +using Fengling.RiskControl.Infrastructure.SeedData; namespace Fengling.RiskControl.Infrastructure; @@ -61,4 +62,13 @@ public class RiskControlDbContext : DbContext builder.Property(l => l.DeviceId).HasMaxLength(100); }); } + + public void SeedData() + { + if (!RiskRules.Any()) + { + RiskRules.AddRange(RiskControlSeedData.GetDefaultRules()); + SaveChanges(); + } + } } diff --git a/Fengling.RiskControl.Infrastructure/SeedData/RiskControlSeedData.cs b/Fengling.RiskControl.Infrastructure/SeedData/RiskControlSeedData.cs new file mode 100644 index 0000000..3bc4809 --- /dev/null +++ b/Fengling.RiskControl.Infrastructure/SeedData/RiskControlSeedData.cs @@ -0,0 +1,57 @@ +using Fengling.RiskControl.Domain.Aggregates.RiskRules; + +namespace Fengling.RiskControl.Infrastructure.SeedData; + +public static class RiskControlSeedData +{ + public static IEnumerable GetDefaultRules() + { + yield return RiskRule.Create( + "高频抽奖限制", + "限制单日抽奖次数,防止沉迷", + RiskRuleType.FrequencyLimit, + RiskRuleAction.Block, + """{"maxCount": 10, "windowMinutes": 1440, "points": 30}""", + priority: 10); + + yield return RiskRule.Create( + "单次大额抽奖限制", + "单次抽奖投入不能超过1000积分", + RiskRuleType.AmountLimit, + RiskRuleAction.Block, + """{"maxAmount": 1000, "points": 40}""", + priority: 9); + + yield return RiskRule.Create( + "设备异常检测", + "同一设备频繁切换账号", + RiskRuleType.DeviceFingerprint, + RiskRuleAction.RequireVerification, + """{"maxAccountsPerDevice": 3, "windowMinutes": 60, "points": 50}""", + priority: 8); + + yield return RiskRule.Create( + "IP地址异常", + "同一IP短时间内大量请求", + RiskRuleType.VelocityCheck, + RiskRuleAction.RateLimit, + """{"maxRequests": 100, "windowMinutes": 1, "points": 20}""", + priority: 7); + + yield return RiskRule.Create( + "行为模式异常", + "检测非正常用户行为模式", + RiskRuleType.BehaviorPattern, + RiskRuleAction.FlagForReview, + """{"patterns": ["rapid_clicks", "pattern_sequences"]}""", + priority: 5); + + yield return RiskRule.Create( + "VIP会员白名单", + "VIP会员享受较低风控等级", + RiskRuleType.Whitelist, + RiskRuleAction.Allow, + """{"vipLevels": [3, 4, 5]}""", + priority: 100); + } +}