feat: add Logs
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using mws.backend.dotnet.domain.Audit;
|
||||
using mws.backend.dotnet.domain.Documents;
|
||||
using mws.backend.dotnet.domain.MasterData;
|
||||
using mws.backend.dotnet.domain.Projects;
|
||||
@@ -20,6 +21,8 @@ public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(op
|
||||
public DbSet<Role> Roles => Set<Role>();
|
||||
public DbSet<RolePermission> RolePermissions => Set<RolePermission>();
|
||||
public DbSet<MasterDataEntry> MasterData => Set<MasterDataEntry>();
|
||||
public DbSet<ActionLog> ActionLogs => Set<ActionLog>();
|
||||
public DbSet<LoginLog> LoginLogs => Set<LoginLog>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using mws.backend.dotnet.domain.Audit;
|
||||
|
||||
namespace mws.backend.dotnet.infrastructure.Persistence.Configuration;
|
||||
|
||||
public class ActionLogConfiguration : IEntityTypeConfiguration<ActionLog>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ActionLog> e)
|
||||
{
|
||||
e.ToTable("action_logs");
|
||||
e.HasKey(x => x.Id);
|
||||
e.Property(x => x.ActorUsername).HasMaxLength(100).IsRequired();
|
||||
e.Property(x => x.Action).HasMaxLength(100).IsRequired();
|
||||
e.Property(x => x.EntityType).HasMaxLength(50).IsRequired();
|
||||
e.Property(x => x.EntityName).HasMaxLength(255);
|
||||
e.Property(x => x.IpAddress).HasMaxLength(45);
|
||||
e.Property(x => x.UserAgent).HasMaxLength(512);
|
||||
e.HasIndex(x => x.CreatedAt);
|
||||
e.HasIndex(x => x.ActorUserId);
|
||||
e.HasIndex(x => x.Action);
|
||||
e.HasIndex(x => x.EntityType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using mws.backend.dotnet.domain.Audit;
|
||||
|
||||
namespace mws.backend.dotnet.infrastructure.Persistence.Configuration;
|
||||
|
||||
public class LoginLogConfiguration : IEntityTypeConfiguration<LoginLog>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<LoginLog> e)
|
||||
{
|
||||
e.ToTable("login_logs");
|
||||
e.HasKey(x => x.Id);
|
||||
e.Property(x => x.Username).HasMaxLength(100).IsRequired();
|
||||
e.Property(x => x.FailureReason).HasMaxLength(100);
|
||||
e.Property(x => x.IpAddress).HasMaxLength(45);
|
||||
e.Property(x => x.UserAgent).HasMaxLength(512);
|
||||
e.HasIndex(x => x.CreatedAt);
|
||||
e.HasIndex(x => x.Username);
|
||||
e.HasIndex(x => x.Success);
|
||||
}
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public static class DbSeeder
|
||||
"Member",
|
||||
screen => screen.Key switch
|
||||
{
|
||||
"users" or "permissions" or "masterdata" => (View: false, Create: false, Edit: false, Delete: false),
|
||||
"users" or "permissions" or "masterdata" or "actionlogs" or "loginlogs" => (View: false, Create: false, Edit: false, Delete: false),
|
||||
"projects" => (View: true, Create: false, Edit: false, Delete: false),
|
||||
_ => (View: true, Create: true, Edit: true, Delete: false),
|
||||
},
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using mws.backend.dotnet.application.Audit;
|
||||
using mws.backend.dotnet.application.Common;
|
||||
using mws.backend.dotnet.application.Common.Repositories;
|
||||
using mws.backend.dotnet.domain.Audit;
|
||||
|
||||
namespace mws.backend.dotnet.infrastructure.Persistence.Repositories;
|
||||
|
||||
public class ActionLogRepository(AppDbContext db) : RepositoryBase<ActionLog>(db), IActionLogRepository
|
||||
{
|
||||
public Task<PagedResult<ActionLog>> SearchAsync(ActionLogFilter filter, int page, int pageSize, CancellationToken ct = default)
|
||||
{
|
||||
var query = Set.AsQueryable();
|
||||
|
||||
if (filter.From is { } from) query = query.Where(x => x.CreatedAt >= from);
|
||||
if (filter.To is { } to) query = query.Where(x => x.CreatedAt <= to);
|
||||
if (!string.IsNullOrWhiteSpace(filter.Actor))
|
||||
{
|
||||
var lower = filter.Actor.Trim().ToLower();
|
||||
query = query.Where(x => x.ActorUsername.ToLower().Contains(lower));
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(filter.Action))
|
||||
{
|
||||
var lower = filter.Action.Trim().ToLower();
|
||||
query = query.Where(x => x.Action.ToLower().Contains(lower));
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(filter.EntityType))
|
||||
{
|
||||
var lower = filter.EntityType.Trim().ToLower();
|
||||
query = query.Where(x => x.EntityType.ToLower().Contains(lower));
|
||||
}
|
||||
if (filter.EntityId is { } entityId) query = query.Where(x => x.EntityId == entityId);
|
||||
|
||||
return query.OrderByDescending(x => x.CreatedAt).ToPagedResultAsync(page, pageSize, ct);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using mws.backend.dotnet.application.Audit;
|
||||
using mws.backend.dotnet.application.Common;
|
||||
using mws.backend.dotnet.application.Common.Repositories;
|
||||
using mws.backend.dotnet.domain.Audit;
|
||||
|
||||
namespace mws.backend.dotnet.infrastructure.Persistence.Repositories;
|
||||
|
||||
public class LoginLogRepository(AppDbContext db) : RepositoryBase<LoginLog>(db), ILoginLogRepository
|
||||
{
|
||||
public Task<PagedResult<LoginLog>> SearchAsync(LoginLogFilter filter, int page, int pageSize, CancellationToken ct = default)
|
||||
{
|
||||
var query = Set.AsQueryable();
|
||||
|
||||
if (filter.From is { } from) query = query.Where(x => x.CreatedAt >= from);
|
||||
if (filter.To is { } to) query = query.Where(x => x.CreatedAt <= to);
|
||||
if (!string.IsNullOrWhiteSpace(filter.Username))
|
||||
{
|
||||
var lower = filter.Username.Trim().ToLower();
|
||||
query = query.Where(x => x.Username.ToLower().Contains(lower));
|
||||
}
|
||||
if (filter.Success is { } success) query = query.Where(x => x.Success == success);
|
||||
|
||||
return query.OrderByDescending(x => x.CreatedAt).ToPagedResultAsync(page, pageSize, ct);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@ public class UnitOfWork : IUnitOfWork
|
||||
Documents = new DocumentRepository(db);
|
||||
Roles = new RoleRepository(db);
|
||||
MasterData = new MasterDataRepository(db);
|
||||
ActionLogs = new ActionLogRepository(db);
|
||||
LoginLogs = new LoginLogRepository(db);
|
||||
}
|
||||
|
||||
public IUserRepository Users { get; }
|
||||
@@ -25,6 +27,8 @@ public class UnitOfWork : IUnitOfWork
|
||||
public IDocumentRepository Documents { get; }
|
||||
public IRoleRepository Roles { get; }
|
||||
public IMasterDataRepository MasterData { get; }
|
||||
public IActionLogRepository ActionLogs { get; }
|
||||
public ILoginLogRepository LoginLogs { get; }
|
||||
|
||||
public Task<int> SaveChangesAsync(CancellationToken ct = default) => _db.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user