Skip to content

Commit

Permalink
Merge pull request #798 from neozhu/refactor_audittrail
Browse files Browse the repository at this point in the history
Fix for ICurrentUserAccessor User ID Retrieval and AuditTrail Enhancements
  • Loading branch information
neozhu authored Nov 9, 2024
2 parents 3768099 + 7ae0ea8 commit 804af81
Show file tree
Hide file tree
Showing 49 changed files with 3,884 additions and 462 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace CleanArchitecture.Blazor.Application.Common.Interfaces.Identity;
using Org.BouncyCastle.Bcpg;

namespace CleanArchitecture.Blazor.Application.Common.Interfaces.Identity;

/// <summary>
/// Interface to access the current user's session information.
Expand Down
8 changes: 7 additions & 1 deletion src/Application/Features/AuditTrails/DTOs/AuditTrailDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ public class AuditTrailDto
[Description("Primary Key")] public string PrimaryKey { get; set; } = default!;
[Description("Show Details")] public bool ShowDetails { get; set; }
[Description("Owner")] public ApplicationUserDto? Owner { get; set; }

[Description("Debug View")]
public string? DebugView { get; set; }
[Description("Error Message")]
public string? ErrorMessage { get; set; }
[Description("Is Successful")]
public bool IsSuccessful=> string.IsNullOrEmpty(ErrorMessage);

}
21 changes: 17 additions & 4 deletions src/Application/Features/Contacts/Caching/ContactCacheKey.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// Defines static methods and properties for managing cache keys and expiration
// settings for Contact-related data. This includes creating unique cache keys for
// various contact queries (such as getting all contacts, contacts by ID, etc.),
// managing the cache expiration tokens to control cache validity, and providing a
// mechanism to refresh cached data in a thread-safe manner.
// </auto-generated>
//------------------------------------------------------------------------------

namespace CleanArchitecture.Blazor.Application.Features.Contacts.Caching;
/// <summary>
/// Static class for managing cache keys and expiration for Contact-related data.
/// </summary>
public static class ContactCacheKey
{

public const string CacheName = "Contact";
// Defines the refresh interval for the cache expiration token
private static readonly TimeSpan RefreshInterval = TimeSpan.FromMinutes(30);
// Object used for locking to ensure thread safety
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,58 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// This file defines the command for adding or editing a contact entity,
// including validation and mapping operations. It handles domain events
// and cache invalidation for updated or newly created contact.
//
// Documentation:
// https://docs.cleanarchitectureblazor.com/features/contact
// </auto-generated>
//------------------------------------------------------------------------------

// Usage:
// This command can be used to add a new contact or edit an existing one.
// It handles caching logic and domain event raising automatically.


using CleanArchitecture.Blazor.Application.Features.Contacts.Caching;
using CleanArchitecture.Blazor.Application.Features.Contacts.Mappers;

namespace CleanArchitecture.Blazor.Application.Features.Contacts.Commands.AddEdit;

public class AddEditContactCommand : ICacheInvalidatorRequest<Result<int>>
public class AddEditContactCommand: ICacheInvalidatorRequest<Result<int>>
{
[Description("Id")]
public int Id { get; set; }
[Description("Name")]
public string? Name { get; set; }
[Description("Id")]
public int Id { get; set; }
[Description("Name")]
public string Name {get;set;}
[Description("Description")]
public string? Description { get; set; }
public string? Description {get;set;}

Check warning on line 38 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 38 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 38 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.
[Description("Email")]
public string? Email { get; set; }
public string? Email {get;set;}

Check warning on line 40 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 40 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 40 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.
[Description("Phone number")]
public string? PhoneNumber { get; set; }
public string? PhoneNumber {get;set;}

Check warning on line 42 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 42 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 42 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.
[Description("Country")]
public string? Country { get; set; }
public string CacheKey => ContactCacheKey.GetAllCacheKey;
public CancellationTokenSource? SharedExpiryTokenSource => ContactCacheKey.GetOrCreateTokenSource();
public string? Country {get;set;}

Check warning on line 44 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 44 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 44 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.


public string CacheKey => ContactCacheKey.GetAllCacheKey;
public CancellationTokenSource? SharedExpiryTokenSource => ContactCacheKey.GetOrCreateTokenSource();

Check warning on line 48 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 48 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 48 in src/Application/Features/Contacts/Commands/AddEdit/AddEditContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.
}

public class AddEditContactCommandHandler : IRequestHandler<AddEditContactCommand, Result<int>>
{
private readonly IApplicationDbContext _context;
public AddEditContactCommandHandler(
IApplicationDbContext context
)
IApplicationDbContext context)
{
_context = context;
}
Expand All @@ -42,20 +66,21 @@ public async Task<Result<int>> Handle(AddEditContactCommand request, Cancellatio
return await Result<int>.FailureAsync($"Contact with id: [{request.Id}] not found.");
}
ContactMapper.ApplyChangesFrom(request,item);
// raise a update domain event
item.AddDomainEvent(new ContactUpdatedEvent(item));
// raise a update domain event
item.AddDomainEvent(new ContactUpdatedEvent(item));
await _context.SaveChangesAsync(cancellationToken);
return await Result<int>.SuccessAsync(item.Id);
}
else
{
var item = ContactMapper.FromEditCommand(request);
// raise a create domain event
item.AddDomainEvent(new ContactCreatedEvent(item));
item.AddDomainEvent(new ContactCreatedEvent(item));
_context.Contacts.Add(item);
await _context.SaveChangesAsync(cancellationToken);
return await Result<int>.SuccessAsync(item.Id);
}

}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// This file defines the validation rules for the AddEditContactCommand
// used to add or edit Contact entities within the CleanArchitecture.Blazor
// application. It enforces maximum field lengths and required properties
// to maintain data integrity and validation standards.
//
// Documentation:
// https://docs.cleanarchitectureblazor.com/features/contact
// </auto-generated>
//------------------------------------------------------------------------------

// Usage:
// This validator enforces constraints on the AddEditContactCommand, such as
// maximum field length for ...

namespace CleanArchitecture.Blazor.Application.Features.Contacts.Commands.AddEdit;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// This file defines the command and its handler for creating a new Contact entity
// within the CleanArchitecture.Blazor application. The command uses caching
// invalidation to ensure data consistency and raises domain events to maintain
// the integrity of the entity lifecycle. It leverages Clean Architecture principles
// for separation of concerns and encapsulation.
//
// Documentation:
// https://docs.cleanarchitectureblazor.com/features/contact
// </auto-generated>
//------------------------------------------------------------------------------

// Usage:
// This command can be used to create a new contact entity in the system. It includes
// the required fields for the contact and automatically raises necessary domain
// events for integration with other bounded contexts in the application.

using CleanArchitecture.Blazor.Application.Features.Contacts.Caching;
using CleanArchitecture.Blazor.Application.Features.Contacts.Mappers;

Expand All @@ -10,7 +35,7 @@ public class CreateContactCommand: ICacheInvalidatorRequest<Result<int>>
[Description("Id")]
public int Id { get; set; }
[Description("Name")]
public string? Name {get;set;}
public string Name {get;set;}
[Description("Description")]
public string? Description {get;set;}

Check warning on line 40 in src/Application/Features/Contacts/Commands/Create/CreateContactCommand.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 40 in src/Application/Features/Contacts/Commands/Create/CreateContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

Check warning on line 40 in src/Application/Features/Contacts/Commands/Create/CreateContactCommand.cs

View workflow job for this annotation

GitHub Actions / Analyze

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.
[Description("Email")]
Expand All @@ -22,22 +47,19 @@ public class CreateContactCommand: ICacheInvalidatorRequest<Result<int>>

public string CacheKey => ContactCacheKey.GetAllCacheKey;
public CancellationTokenSource? SharedExpiryTokenSource => ContactCacheKey.GetOrCreateTokenSource();

}

public class CreateContactCommandHandler : IRequestHandler<CreateContactCommand, Result<int>>
{
private readonly IApplicationDbContext _context;

public CreateContactCommandHandler(
IApplicationDbContext context
)
IApplicationDbContext context)
{
_context = context;
}
public async Task<Result<int>> Handle(CreateContactCommand request, CancellationToken cancellationToken)
{
var item =ContactMapper.FromCreateCommand(request);
var item = ContactMapper.FromCreateCommand(request);
// raise a create domain event
item.AddDomainEvent(new ContactCreatedEvent(item));
_context.Contacts.Add(item);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// This file defines the validation rules for the CreateContactCommand,
// used to create Contact entities within the CleanArchitecture.Blazor
// application. It ensures that essential fields are validated correctly,
// including maximum lengths and mandatory requirements for required fields.
//
// Documentation:
// https://docs.cleanarchitectureblazor.com/features/contact
// </auto-generated>
//------------------------------------------------------------------------------

// Usage:
// This validator is used to ensure that a CreateContactCommand meets the required
// validation criteria. It enforces constraints like maximum field lengths and
// ensures that the Name field is not empty before proceeding with the command execution.

namespace CleanArchitecture.Blazor.Application.Features.Contacts.Commands.Create;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// This file defines the command and its handler for deleting one or more
// Contact entities from the CleanArchitecture.Blazor application. It
// implements caching invalidation logic to ensure that data consistency is
// maintained. Domain events are triggered for deleted entities to support
// integration with other parts of the system.
// for separation of concerns and encapsulation.
//
// Documentation:
// https://docs.cleanarchitectureblazor.com/features/contact
// </auto-generated>
//------------------------------------------------------------------------------

// Usage:
// This command can be used to delete multiple Contacts from the system by specifying
// their IDs. The handler also raises domain events for each deleted contact to
// notify other bounded contexts and invalidate relevant cache entries.

using CleanArchitecture.Blazor.Application.Features.Contacts.Caching;


namespace CleanArchitecture.Blazor.Application.Features.Contacts.Commands.Delete;

public class DeleteContactCommand : ICacheInvalidatorRequest<Result<int>>
public class DeleteContactCommand: ICacheInvalidatorRequest<Result<int>>
{
public int[] Id { get; }
public string CacheKey => ContactCacheKey.GetAllCacheKey;
public CancellationTokenSource? SharedExpiryTokenSource => ContactCacheKey.GetOrCreateTokenSource();
public DeleteContactCommand(int[] id)
{
Id = id;
}
public int[] Id { get; }
public string CacheKey => ContactCacheKey.GetAllCacheKey;
public CancellationTokenSource? SharedExpiryTokenSource => ContactCacheKey.GetOrCreateTokenSource();
public DeleteContactCommand(int[] id)
{
Id = id;
}
}

public class DeleteContactCommandHandler :
public class DeleteContactCommandHandler :
IRequestHandler<DeleteContactCommand, Result<int>>

{
private readonly IApplicationDbContext _context;
public DeleteContactCommandHandler(
IApplicationDbContext context
)
IApplicationDbContext context)
{
_context = context;
}
public async Task<Result<int>> Handle(DeleteContactCommand request, CancellationToken cancellationToken)
{
var items = await _context.Contacts.Where(x => request.Id.Contains(x.Id)).ToListAsync(cancellationToken);
var items = await _context.Contacts.Where(x=>request.Id.Contains(x.Id)).ToListAsync(cancellationToken);
foreach (var item in items)
{
// raise a delete domain event
item.AddDomainEvent(new ContactDeletedEvent(item));
// raise a delete domain event
item.AddDomainEvent(new ContactDeletedEvent(item));
_context.Contacts.Remove(item);
}
var result = await _context.SaveChangesAsync(cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This file is part of the CleanArchitecture.Blazor project.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Author: neozhu
// Created Date: 2024-11-08
// Last Modified: 2024-11-08
// Description:
// This file defines the validation rules for the DeleteContactCommand used
// to delete Contact entities within the CleanArchitecture.Blazor application.
// It ensures that the command has valid input, particularly verifying that the
// list of contact IDs to delete is not null and contains only positive IDs.
//
// Documentation:
// https://docs.cleanarchitectureblazor.com/features/contact
// </auto-generated>
//------------------------------------------------------------------------------

// Usage:
// This validator ensures that the DeleteContactCommand is valid before attempting
// to delete contact records from the system. It verifies that the ID list is not
// null and that all IDs are greater than zero.

namespace CleanArchitecture.Blazor.Application.Features.Contacts.Commands.Delete;

Expand Down
Loading

0 comments on commit 804af81

Please sign in to comment.