feat(risk-control): add repository layer

This commit is contained in:
Sam 2026-02-05 14:54:07 +08:00
parent 22d0427df9
commit d6f5c00554
9 changed files with 349 additions and 0 deletions

View File

@ -0,0 +1,13 @@
using Fengling.RiskControl.Domain.Aggregates.LotteryActivities;
namespace Fengling.RiskControl.Domain.Repositories;
public interface ILotteryActivityRepository
{
Task<LotteryActivity?> GetByIdAsync(long id);
Task<IEnumerable<LotteryActivity>> GetByMemberIdAsync(long memberId);
Task<IEnumerable<LotteryActivity>> GetRecentByMemberIdAsync(long memberId, int count);
Task AddAsync(LotteryActivity activity);
Task UpdateAsync(LotteryActivity activity);
Task DeleteAsync(LotteryActivity activity);
}

View File

@ -0,0 +1,14 @@
using Fengling.RiskControl.Domain.Aggregates.RiskAlerts;
namespace Fengling.RiskControl.Domain.Repositories;
public interface IRiskAlertRepository
{
Task<RiskAlert?> GetByIdAsync(long id);
Task<IEnumerable<RiskAlert>> GetByMemberIdAsync(long memberId);
Task<IEnumerable<RiskAlert>> GetPendingAlertsAsync();
Task<IEnumerable<RiskAlert>> GetAlertsByPriorityAsync(RiskAlertPriority priority);
Task AddAsync(RiskAlert alert);
Task UpdateAsync(RiskAlert alert);
Task DeleteAsync(RiskAlert alert);
}

View File

@ -0,0 +1,14 @@
using Fengling.RiskControl.Domain.Aggregates.RiskRules;
namespace Fengling.RiskControl.Domain.Repositories;
public interface IRiskRuleRepository
{
Task<RiskRule?> GetByIdAsync(long id);
Task<IEnumerable<RiskRule>> GetActiveRulesAsync();
Task<IEnumerable<RiskRule>> GetRulesByTypeAsync(RiskRuleType type);
Task<IEnumerable<RiskRule>> GetRulesForEvaluationAsync(string entityType, string actionType);
Task AddAsync(RiskRule rule);
Task UpdateAsync(RiskRule rule);
Task DeleteAsync(RiskRule rule);
}

View File

@ -0,0 +1,14 @@
using Fengling.RiskControl.Domain.Aggregates.RiskScores;
namespace Fengling.RiskControl.Domain.Repositories;
public interface IRiskScoreRepository
{
Task<RiskScore?> GetByIdAsync(long id);
Task<RiskScore?> GetByMemberAndEntityAsync(long memberId, string entityType, string entityId);
Task<RiskScore?> GetActiveByMemberAndEntityTypeAsync(long memberId, string entityType);
Task<IEnumerable<RiskScore>> GetByMemberIdAsync(long memberId);
Task AddAsync(RiskScore score);
Task UpdateAsync(RiskScore score);
Task DeleteAsync(RiskScore score);
}

View File

@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore;
using Fengling.RiskControl.Domain.Aggregates.LotteryActivities;
using Fengling.RiskControl.Domain.Repositories;
namespace Fengling.RiskControl.Infrastructure.Repositories;
public class LotteryActivityRepository : ILotteryActivityRepository
{
private readonly RiskControlDbContext _context;
public LotteryActivityRepository(RiskControlDbContext context)
{
_context = context;
}
public async Task<LotteryActivity?> GetByIdAsync(long id)
{
return await _context.LotteryActivities.FindAsync(id);
}
public async Task<IEnumerable<LotteryActivity>> GetByMemberIdAsync(long memberId)
{
return await _context.LotteryActivities
.Where(l => l.MemberId == memberId)
.OrderByDescending(l => l.CreatedAt)
.ToListAsync();
}
public async Task<IEnumerable<LotteryActivity>> GetRecentByMemberIdAsync(long memberId, int count)
{
return await _context.LotteryActivities
.Where(l => l.MemberId == memberId)
.OrderByDescending(l => l.CreatedAt)
.Take(count)
.ToListAsync();
}
public async Task AddAsync(LotteryActivity activity)
{
await _context.LotteryActivities.AddAsync(activity);
}
public async Task UpdateAsync(LotteryActivity activity)
{
_context.LotteryActivities.Update(activity);
await Task.CompletedTask;
}
public async Task DeleteAsync(LotteryActivity activity)
{
_context.LotteryActivities.Remove(activity);
await Task.CompletedTask;
}
}

View File

@ -0,0 +1,59 @@
using Microsoft.EntityFrameworkCore;
using Fengling.RiskControl.Domain.Aggregates.RiskAlerts;
using Fengling.RiskControl.Domain.Repositories;
namespace Fengling.RiskControl.Infrastructure.Repositories;
public class RiskAlertRepository : IRiskAlertRepository
{
private readonly RiskControlDbContext _context;
public RiskAlertRepository(RiskControlDbContext context)
{
_context = context;
}
public async Task<RiskAlert?> GetByIdAsync(long id)
{
return await _context.RiskAlerts.FindAsync(id);
}
public async Task<IEnumerable<RiskAlert>> GetByMemberIdAsync(long memberId)
{
return await _context.RiskAlerts
.Where(a => a.MemberId == memberId)
.ToListAsync();
}
public async Task<IEnumerable<RiskAlert>> GetPendingAlertsAsync()
{
return await _context.RiskAlerts
.Where(a => a.Status == RiskAlertStatus.Pending)
.OrderByDescending(a => a.Priority)
.ToListAsync();
}
public async Task<IEnumerable<RiskAlert>> GetAlertsByPriorityAsync(RiskAlertPriority priority)
{
return await _context.RiskAlerts
.Where(a => a.Priority == priority)
.ToListAsync();
}
public async Task AddAsync(RiskAlert alert)
{
await _context.RiskAlerts.AddAsync(alert);
}
public async Task UpdateAsync(RiskAlert alert)
{
_context.RiskAlerts.Update(alert);
await Task.CompletedTask;
}
public async Task DeleteAsync(RiskAlert alert)
{
_context.RiskAlerts.Remove(alert);
await Task.CompletedTask;
}
}

View File

@ -0,0 +1,59 @@
using Microsoft.EntityFrameworkCore;
using Fengling.RiskControl.Domain.Aggregates.RiskRules;
using Fengling.RiskControl.Domain.Repositories;
namespace Fengling.RiskControl.Infrastructure.Repositories;
public class RiskRuleRepository : IRiskRuleRepository
{
private readonly RiskControlDbContext _context;
public RiskRuleRepository(RiskControlDbContext context)
{
_context = context;
}
public async Task<RiskRule?> GetByIdAsync(long id)
{
return await _context.RiskRules.FindAsync(id);
}
public async Task<IEnumerable<RiskRule>> GetActiveRulesAsync()
{
return await _context.RiskRules
.Where(r => r.IsActive)
.OrderByDescending(r => r.Priority)
.ToListAsync();
}
public async Task<IEnumerable<RiskRule>> GetRulesByTypeAsync(RiskRuleType type)
{
return await _context.RiskRules
.Where(r => r.RuleType == type && r.IsActive)
.ToListAsync();
}
public async Task<IEnumerable<RiskRule>> GetRulesForEvaluationAsync(string entityType, string actionType)
{
return await _context.RiskRules
.Where(r => r.IsActive)
.ToListAsync();
}
public async Task AddAsync(RiskRule rule)
{
await _context.RiskRules.AddAsync(rule);
}
public async Task UpdateAsync(RiskRule rule)
{
_context.RiskRules.Update(rule);
await Task.CompletedTask;
}
public async Task DeleteAsync(RiskRule rule)
{
_context.RiskRules.Remove(rule);
await Task.CompletedTask;
}
}

View File

@ -0,0 +1,58 @@
using Microsoft.EntityFrameworkCore;
using Fengling.RiskControl.Domain.Aggregates.RiskScores;
using Fengling.RiskControl.Domain.Repositories;
namespace Fengling.RiskControl.Infrastructure.Repositories;
public class RiskScoreRepository : IRiskScoreRepository
{
private readonly RiskControlDbContext _context;
public RiskScoreRepository(RiskControlDbContext context)
{
_context = context;
}
public async Task<RiskScore?> GetByIdAsync(long id)
{
return await _context.RiskScores.FindAsync(id);
}
public async Task<RiskScore?> GetByMemberAndEntityAsync(long memberId, string entityType, string entityId)
{
return await _context.RiskScores
.FirstOrDefaultAsync(s => s.MemberId == memberId && s.EntityType == entityType && s.EntityId == entityId);
}
public async Task<RiskScore?> GetActiveByMemberAndEntityTypeAsync(long memberId, string entityType)
{
return await _context.RiskScores
.Where(s => s.MemberId == memberId && s.EntityType == entityType)
.OrderByDescending(s => s.CreatedAt)
.FirstOrDefaultAsync();
}
public async Task<IEnumerable<RiskScore>> GetByMemberIdAsync(long memberId)
{
return await _context.RiskScores
.Where(s => s.MemberId == memberId)
.ToListAsync();
}
public async Task AddAsync(RiskScore score)
{
await _context.RiskScores.AddAsync(score);
}
public async Task UpdateAsync(RiskScore score)
{
_context.RiskScores.Update(score);
await Task.CompletedTask;
}
public async Task DeleteAsync(RiskScore score)
{
_context.RiskScores.Remove(score);
await Task.CompletedTask;
}
}

View File

@ -0,0 +1,64 @@
using Microsoft.EntityFrameworkCore;
using NetCorePal.Extensions.Domain;
using Fengling.RiskControl.Domain.Aggregates.RiskRules;
using Fengling.RiskControl.Domain.Aggregates.RiskScores;
using Fengling.RiskControl.Domain.Aggregates.RiskAlerts;
using Fengling.RiskControl.Domain.Aggregates.LotteryActivities;
namespace Fengling.RiskControl.Infrastructure;
public class RiskControlDbContext : DbContext
{
public DbSet<RiskRule> RiskRules => Set<RiskRule>();
public DbSet<RiskScore> RiskScores => Set<RiskScore>();
public DbSet<RiskAlert> RiskAlerts => Set<RiskAlert>();
public DbSet<LotteryActivity> LotteryActivities => Set<LotteryActivity>();
private RiskControlDbContext() { }
public RiskControlDbContext(DbContextOptions<RiskControlDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<RiskRule>(builder =>
{
builder.ToTable("rc_risk_rules");
builder.HasKey(r => r.Id);
builder.Property(r => r.Name).HasMaxLength(100).IsRequired();
builder.Property(r => r.Description).HasMaxLength(500);
builder.Property(r => r.ConfigJson).HasColumnName("config_json");
builder.Property(r => r.IsActive).HasDefaultValue(true);
});
modelBuilder.Entity<RiskScore>(builder =>
{
builder.ToTable("rc_risk_scores");
builder.HasKey(s => s.Id);
builder.Property(s => s.MemberId).IsRequired();
builder.Property(s => s.EntityType).HasMaxLength(50).IsRequired();
builder.Property(s => s.EntityId).HasMaxLength(100).IsRequired();
});
modelBuilder.Entity<RiskAlert>(builder =>
{
builder.ToTable("rc_risk_alerts");
builder.HasKey(a => a.Id);
builder.Property(a => a.MemberId).IsRequired();
builder.Property(a => a.AlertType).HasMaxLength(50).IsRequired();
builder.Property(a => a.Description).HasMaxLength(500);
});
modelBuilder.Entity<LotteryActivity>(builder =>
{
builder.ToTable("rc_lottery_activities");
builder.HasKey(l => l.Id);
builder.Property(l => l.MemberId).IsRequired();
builder.Property(l => l.ActivityType).HasMaxLength(50).IsRequired();
builder.Property(l => l.IpAddress).HasMaxLength(50);
builder.Property(l => l.DeviceId).HasMaxLength(100);
});
}
}