feat(Notfication),feat(NotificationCQRS).feat(NotificationController)
- Add notification marten entity - Add notification service by CQRS and mediatR - Add notification controllermaster
parent
8bb2713069
commit
bb6cba1ed9
|
@ -0,0 +1,21 @@
|
|||
namespace Brizco.Api.Controllers;
|
||||
|
||||
public class NotificationController : ICarterModule
|
||||
{
|
||||
public void AddRoutes(IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.NewVersionedApi("Notifications")
|
||||
.MapGroup("api/notification");
|
||||
|
||||
group.MapGet("", GetUserNotificationsAsync)
|
||||
.WithDisplayName("Get User Notifications")
|
||||
.WithDescription("Get user notifications , by JWT user id")
|
||||
.RequireAuthorization(builder=>builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
}
|
||||
|
||||
private async Task<IResult> GetUserNotificationsAsync([FromQuery] int page, [FromQuery] int count,
|
||||
[FromServices] IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetNotificationsQuery(page, count), cancellationToken));
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Marten;
|
||||
using Brizco.Core.MartenServices.Abstracts;
|
||||
using Marten;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Brizco.Api.Controllers;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
public interface IMartenEntity
|
||||
{
|
||||
string CreatedBy { get; }
|
||||
string ModifiedBy { get; }
|
||||
DateTime CreatedAt { get; }
|
||||
DateTime ModifiedAt { get; }
|
||||
//string CreatedBy { get; }
|
||||
//string ModifiedBy { get; }
|
||||
//DateTime CreatedAt { get; }
|
||||
//DateTime ModifiedAt { get; }
|
||||
}
|
|
@ -6,21 +6,22 @@ public class MartenEntity : IMartenEntity
|
|||
public Guid Id { get; set; }
|
||||
|
||||
|
||||
[Display(Name = "تاریخ ساخت")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
//[Display(Name = "تاریخ ساخت")]
|
||||
//public DateTime CreatedAt { get; set; }
|
||||
|
||||
[Display(Name = "ساخته شده توسط")]
|
||||
public string CreatedBy { get; set; } = string.Empty;
|
||||
//[Display(Name = "ساخته شده توسط")]
|
||||
//public string CreatedBy { get; set; } = string.Empty;
|
||||
|
||||
[Display(Name = "اخرین تغییر در")]
|
||||
public DateTime ModifiedAt { get; set; }
|
||||
//[Display(Name = "اخرین تغییر در")]
|
||||
//public DateTime ModifiedAt { get; set; }
|
||||
|
||||
[Display(Name = "اخرین تغییر توسط")]
|
||||
public string ModifiedBy { get; set; } = string.Empty;
|
||||
//[Display(Name = "اخرین تغییر توسط")]
|
||||
//public string ModifiedBy { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public Guid ComplexId { get; set; }
|
||||
|
||||
public bool Equals(ApiEntity other)
|
||||
public bool Equals(MartenEntity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
@ -32,7 +33,7 @@ public class MartenEntity : IMartenEntity
|
|||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((ApiEntity)obj);
|
||||
return Equals((MartenEntity)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
<Using Include="Brizco.Core.CoreServices.Abstracts" />
|
||||
<Using Include="Brizco.Core.CoreServices.ReportServices.Commands" />
|
||||
<Using Include="Brizco.Core.EntityServices.Abstracts" />
|
||||
<Using Include="Brizco.Core.MartenServices.Abstracts" />
|
||||
<Using Include="Brizco.Domain" />
|
||||
<Using Include="Brizco.Domain.CommandQueries.Commands" />
|
||||
<Using Include="Brizco.Domain.CommandQueries.Queries" />
|
||||
<Using Include="Brizco.Domain.Dtos.LargeDtos" />
|
||||
|
@ -46,6 +48,7 @@
|
|||
<Using Include="Brizco.Domain.Enums" />
|
||||
<Using Include="Brizco.Domain.Mappers" />
|
||||
<Using Include="Brizco.Domain.MartenEntities.Brews" />
|
||||
<Using Include="Brizco.Domain.MartenEntities.Notifications" />
|
||||
<Using Include="Brizco.Domain.Models.Settings" />
|
||||
<Using Include="Brizco.Repository.Abstracts" />
|
||||
<Using Include="Brizco.Repository.Repositories.Base.Contracts" />
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
namespace Brizco.Core.EntityServices.Abstracts;
|
||||
|
||||
public interface IBrewService : IScopedDependency
|
||||
{
|
||||
public Task<object> GetLastBrewAsync(string recipeName, CancellationToken cancellationToken = default);
|
||||
public Task<BaseRecipeLDto> GetBrewAsync(string recipeName , CancellationToken cancellationToken = default);
|
||||
public Task AddBrewAsync(string recipeName,JsonDocument recipeObj, CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Brizco.Core.MartenServices.Abstracts;
|
||||
|
||||
public interface IBrewService : IScopedDependency
|
||||
{
|
||||
public Task<object> GetLastBrewAsync(string recipeName, CancellationToken cancellationToken = default);
|
||||
public Task<BaseRecipeLDto> GetBrewAsync(string recipeName, CancellationToken cancellationToken = default);
|
||||
public Task AddBrewAsync(string recipeName, JsonDocument recipeObj, CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -1,15 +1,14 @@
|
|||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
using Brizco.Domain;
|
||||
|
||||
namespace Brizco.Core.EntityServices;
|
||||
namespace Brizco.Core.MartenServices;
|
||||
|
||||
public class BrewService : IBrewService
|
||||
{
|
||||
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public BrewService(IMartenRepositoryWrapper martenRepositoryWrapper,ICurrentUserService currentUserService)
|
||||
public BrewService(IMartenRepositoryWrapper martenRepositoryWrapper, ICurrentUserService currentUserService)
|
||||
{
|
||||
_martenRepositoryWrapper = martenRepositoryWrapper;
|
||||
_currentUserService = currentUserService;
|
||||
|
@ -20,10 +19,10 @@ public class BrewService : IBrewService
|
|||
if (type == null)
|
||||
throw new AppException("Recipe not found", ApiResultStatusCode.NotFound);
|
||||
if (_currentUserService.ComplexId == null)
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest,"Complex id is null");
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is null");
|
||||
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong");
|
||||
|
||||
|
||||
var baseRecipe = await _martenRepositoryWrapper.SetRepository<BaseBrew>()
|
||||
.GetEntityAsync(s => s.ComplexId == complexId && s.Name == recipeName, cancellationToken);
|
||||
object? recipe;
|
||||
|
@ -49,7 +48,7 @@ public class BrewService : IBrewService
|
|||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong");
|
||||
|
||||
var baseRecipe = await _martenRepositoryWrapper.SetRepository<BaseBrew>()
|
||||
.GetEntityAsync(s =>s.ComplexId==complexId && s.Name == recipeName, cancellationToken);
|
||||
.GetEntityAsync(s => s.ComplexId == complexId && s.Name == recipeName, cancellationToken);
|
||||
object? recipe;
|
||||
if (baseRecipe == null)
|
||||
{
|
||||
|
@ -92,7 +91,7 @@ public class BrewService : IBrewService
|
|||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong");
|
||||
|
||||
var baseRecipe = await _martenRepositoryWrapper.SetRepository<BaseBrew>()
|
||||
.GetEntityAsync(s =>s.ComplexId == complexId && s.Name == recipeName, cancellationToken);
|
||||
.GetEntityAsync(s => s.ComplexId == complexId && s.Name == recipeName, cancellationToken);
|
||||
|
||||
if (baseRecipe == null)
|
||||
{
|
|
@ -0,0 +1,4 @@
|
|||
namespace Brizco.Domain.CommandQueries.Commands;
|
||||
|
||||
public record CreateNotificationCommand(string Message,Guid UserId) : IRequest<Guid>;
|
||||
public record ReadNotificationCommand(Guid Id) : IRequest<bool>;
|
|
@ -0,0 +1,5 @@
|
|||
using Brizco.Domain.MartenEntities.Notifications;
|
||||
|
||||
namespace Brizco.Domain.CommandQueries.Queries;
|
||||
|
||||
public record GetNotificationsQuery(int Page,int Count, Guid? UserId=null) : IRequest<List<Notification>>;
|
|
@ -6,5 +6,4 @@ public class BaseBrew : MartenEntity
|
|||
public string CurrentBrewJson { get; set; } = string.Empty;
|
||||
public string DotnetType { get; set; } = string.Empty;
|
||||
public List<string> PastBrewsJson { get; set; } = new();
|
||||
public Guid ComplexId { get; set; }
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Brizco.Domain.MartenEntities.Notifications;
|
||||
|
||||
public class Notification : MartenEntity
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public bool IsRead { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
|
@ -24,6 +24,12 @@ public class MartenRepository<TMartenEntity> : IMartenRepository<TMartenEntity>
|
|||
var entities = await session.Query<TMartenEntity>().Where(expression).ToListAsync(cancellation);
|
||||
return entities.ToList();
|
||||
}
|
||||
public async Task<IQueryable<TMartenEntity>> GetQueryAsync(Expression<Func<TMartenEntity, bool>> expression)
|
||||
{
|
||||
await using var session = _documentStore.QuerySession();
|
||||
var entities = session.Query<TMartenEntity>().Where(expression);
|
||||
return entities;
|
||||
}
|
||||
|
||||
public async Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="MartenHandlers\Notifications\" />
|
||||
<Folder Include="Models\" />
|
||||
<Folder Include="Extensions\" />
|
||||
<Folder Include="Services\Contracts\" />
|
||||
|
@ -47,6 +48,7 @@
|
|||
<Using Include="Brizco.Domain.Dtos.SmallDtos" />
|
||||
<Using Include="Brizco.Domain.Entities.Complex" />
|
||||
<Using Include="Brizco.Repository.Abstracts" />
|
||||
<Using Include="Brizco.Repository.Repositories.Marten" />
|
||||
<Using Include="MediatR" />
|
||||
<Using Include="Brizco.Common.Extensions" />
|
||||
<Using Include="Brizco.Common.Models" />
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using Brizco.Domain.MartenEntities.Notifications;
|
||||
|
||||
namespace Brizco.Repository.MartenHandlers.Notifications;
|
||||
|
||||
public class CreateNotificationHandlerCommand : IRequestHandler<CreateNotificationCommand,Guid>
|
||||
{
|
||||
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public CreateNotificationHandlerCommand(IMartenRepositoryWrapper martenRepositoryWrapper, ICurrentUserService currentUserService)
|
||||
{
|
||||
_martenRepositoryWrapper = martenRepositoryWrapper;
|
||||
_currentUserService = currentUserService;
|
||||
}
|
||||
public async Task<Guid> Handle(CreateNotificationCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_currentUserService.ComplexId == null)
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is null");
|
||||
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong");
|
||||
var notification = new Notification
|
||||
{
|
||||
Message = request.Message,
|
||||
UserId = request.UserId,
|
||||
ComplexId = complexId,
|
||||
CreatedAt = DateTime.Now
|
||||
};
|
||||
|
||||
await _martenRepositoryWrapper.SetRepository<Notification>()
|
||||
.AddOrUpdateEntityAsync(notification, cancellationToken);
|
||||
return notification.Id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using Brizco.Domain.MartenEntities.Notifications;
|
||||
|
||||
namespace Brizco.Repository.MartenHandlers.Notifications;
|
||||
|
||||
public class GetNotificationsQueryHandler : IRequestHandler<GetNotificationsQuery,List<Notification>>
|
||||
{
|
||||
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public GetNotificationsQueryHandler(IMartenRepositoryWrapper martenRepositoryWrapper,ICurrentUserService currentUserService)
|
||||
{
|
||||
_martenRepositoryWrapper = martenRepositoryWrapper;
|
||||
_currentUserService = currentUserService;
|
||||
}
|
||||
|
||||
public async Task<List<Notification>> Handle(GetNotificationsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
if (_currentUserService.ComplexId == null)
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is null");
|
||||
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong");
|
||||
|
||||
if (request.UserId == default)
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "User id is null");
|
||||
Guid userId;
|
||||
if (request.UserId == null)
|
||||
{
|
||||
if (_currentUserService.UserId == null)
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "User id is null");
|
||||
if (!Guid.TryParse(_currentUserService.UserId, out userId))
|
||||
throw new BaseApiException(ApiResultStatusCode.BadRequest, "User id is wrong");
|
||||
}
|
||||
else
|
||||
userId = request.UserId.Value;
|
||||
|
||||
var notifications = await _martenRepositoryWrapper.SetRepository<Notification>()
|
||||
.GetQueryAsync(n => n.ComplexId == complexId && n.UserId == userId);
|
||||
var response = await notifications.Take(new Range(request.Page * request.Count, (request.Page * request.Count) + request.Count))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Brizco.Domain.MartenEntities.Notifications;
|
||||
|
||||
namespace Brizco.Repository.MartenHandlers.Notifications;
|
||||
|
||||
public class ReadNotificationCommandHandler : IRequestHandler<ReadNotificationCommand, bool>
|
||||
{
|
||||
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public ReadNotificationCommandHandler(IMartenRepositoryWrapper martenRepositoryWrapper, ICurrentUserService currentUserService)
|
||||
{
|
||||
_martenRepositoryWrapper = martenRepositoryWrapper;
|
||||
_currentUserService = currentUserService;
|
||||
}
|
||||
public async Task<bool> Handle(ReadNotificationCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var notification = await _martenRepositoryWrapper.SetRepository<Notification>()
|
||||
.GetEntityAsync(request.Id, cancellationToken);
|
||||
if (notification == null)
|
||||
throw new BaseApiException(ApiResultStatusCode.NotFound,"Notification not found");
|
||||
|
||||
notification.IsRead = true;
|
||||
|
||||
await _martenRepositoryWrapper.SetRepository<Notification>()
|
||||
.AddOrUpdateEntityAsync(notification, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ public interface IMartenRepository<TMartenEntity> : IScopedDependency where TMar
|
|||
{
|
||||
Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation = default);
|
||||
Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default);
|
||||
Task<IQueryable<TMartenEntity>> GetQueryAsync(Expression<Func<TMartenEntity, bool>> expression);
|
||||
|
||||
Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation = default);
|
||||
Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default);
|
||||
|
|
Loading…
Reference in New Issue