Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ await _publishEndPoint.Publish<CreateUserInitiatedFailed>(new ()
}
}

public class CreateUserInitiatedConsumerDefinition: ConsumerDefinition<CreateUserInitiatedConsumer>
public class CreateUserInitiatedConsumerDefinition : ConsumerDefinition<CreateUserInitiatedConsumer>
{
public CreateUserInitiatedConsumerDefinition()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class ReviewDto
{
public Guid ReviewId { get; set; }
public Guid Id { get; set; }
public Guid MovieId { get; set; }

public string Content { get; set; } = string.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace ReviewService.Application.Interfaces.Operations;

public interface IReviewService
{
Task<IEnumerable<ReviewDto>> GetRecentReviewsForUsersAsync(IEnumerable<Guid> userIds, int count = 3);
Task<IEnumerable<ReviewDto>> GetReviewsByMovieIdAsync(Guid movieId);
Task<Guid> CreateReviewAsync(ReviewDto reviewDto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using MediatR;
using ReviewService.Application.DTO.Reviews;

namespace ReviewService.Application.Orchestration.Queries;

public class GetRecentReviewsForUsersQuery : IRequest<IEnumerable<ReviewDto>>
{
public IEnumerable<Guid> UserIds { get; set; } = [];
public int Count { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using MediatR;
using ReviewService.Application.DTO.Reviews;
using ReviewService.Application.Interfaces.Operations;

namespace ReviewService.Application.Orchestration.Queries
{
public class GetRecentReviewsForUsersQueryHandler : IRequestHandler<GetRecentReviewsForUsersQuery, IEnumerable<ReviewDto>>
{
private readonly IReviewService _reviewService;
public GetRecentReviewsForUsersQueryHandler(IReviewService reviewService)
{
_reviewService = reviewService;
}
public async Task<IEnumerable<ReviewDto>> Handle(GetRecentReviewsForUsersQuery request, CancellationToken cancellationToken)
{
return await _reviewService.GetRecentReviewsForUsersAsync(request.UserIds, request.Count).ConfigureAwait(false); ;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,18 @@ public async Task<Guid> CreateReviewAsync(ReviewDto reviewDto)
throw;
}
}

public async Task<IEnumerable<ReviewDto>> GetRecentReviewsForUsersAsync(IEnumerable<Guid> userIds, int count = 3)
{
try
{
var results = await _reviewRepository.GetRecentReviewsForUsersAsync(userIds, count);
return _mapper.Map<IEnumerable<Review>, IEnumerable<ReviewDto>>(results);
}
catch (Exception)
{

throw;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ public class Review : IEntity
public DateTime CreatedOn { get; set; } = DateTime.UtcNow;
public IEnumerable<string> UpvotedBy { get; set; } = [];
public IEnumerable<string> DownvotedBy { get; set; } = [];
public int Rating { get; set; } = 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace ReviewService.Domain.Repositories;
public interface IGenericRepository<TEntity> where TEntity : class, IEntity, new()
{
Task<IEnumerable<TEntity>> GetAll();
Task<TEntity> GetByIdAsync(long id);
Task<TEntity> GetByIdAsync(Guid id);
Task<TEntity> AddAsync(TEntity entity);
Task<TEntity> UpdateAsync(TEntity entity);
Task<TEntity> DeleteAsync(TEntity entity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface IReviewRepository : IGenericRepository<Review>
Task<IEnumerable<Review>> GetReviewsByUserIdAsync(Guid userId);
Task<IEnumerable<Review>> GetReviewsByRatingAsync(int rating);
Task<IEnumerable<Review>> GetReviewsByDateRangeAsync(DateTime startDate, DateTime endDate);
Task<IEnumerable<Review>> GetRecentReviewsForUsersAsync(IEnumerable<Guid> userIds, int count = 3);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ public class ReviewDocument:Entity
[Field("rating")]
public int Rating { get; set; }

[Field("userName")]
public string UserName { get; set; } = string.Empty;

[Field("author")]
public string Author { get; set; } = string.Empty;

[Field("createdOn")]
public DateTime CreatedOn { get; set; } = DateTime.UtcNow;

}
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
using ReviewService.Domain.Entities;
using AutoMapper;
using MongoDB.Driver;
using MongoDB.Entities;
using ReviewService.Domain.Repositories;

namespace ReviewService.Infrastructure.Repository.Repositories;

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class, IEntity, new()
public class GenericRepository<TDocument,TDomain>(IMongoDatabase database, IMapper mapper, string collectionName) : IGenericRepository<TDomain>
where TDomain : class, Domain.Entities.IEntity, new()
where TDocument : Entity
{
public Task<TEntity> AddAsync(TEntity entity)
protected readonly IMapper Mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
protected IMongoDatabase Database => database ?? throw new ArgumentNullException(nameof(database));
protected IMongoCollection<TDocument> Collection => database.GetCollection<TDocument>(collectionName ?? throw new ArgumentNullException(nameof(collectionName)));
public async Task<IEnumerable<TDomain>> GetAll()
{
throw new NotImplementedException();
var result = await Collection.Find(Builders<TDocument>.Filter.Empty).ToCursorAsync().ConfigureAwait(false);
return Mapper.Map<IEnumerable<TDomain>>(result.ToEnumerable()) ?? throw new InvalidOperationException("No entities found in the collection.");
}

public Task<TEntity> DeleteAsync(TEntity entity)
public async Task<TDomain> GetByIdAsync(Guid id)
{
throw new NotImplementedException();
var filter = Builders<TDocument>.Filter.Eq(e => e.ID, id.ToString());
var entity = await Collection.Find(filter).FirstOrDefaultAsync().ConfigureAwait(false);
return Mapper.Map<TDomain>(entity) ?? throw new KeyNotFoundException($"Entity with ID {id} not found.");
}

public Task<IEnumerable<TEntity>> GetAll()
public async Task<TDomain> AddAsync(TDomain entity)
{
throw new NotImplementedException();
var entityDocument = Mapper.Map<TDocument>(entity) ?? throw new ArgumentNullException(nameof(entity), "Entity cannot be null.");
await Collection.InsertOneAsync(entityDocument).ConfigureAwait(false);
return entity;
}

public Task<TEntity> GetByIdAsync(long id)
public async Task<TDomain> UpdateAsync(TDomain entity)
{
throw new NotImplementedException();
var entityDocument = Mapper.Map<TDocument>(entity) ?? throw new ArgumentNullException(nameof(entity), "Entity cannot be null.");
var filter = Builders<TDocument>.Filter.Eq(e => e.ID, entity.Id.ToString());
await Collection.ReplaceOneAsync(filter,entityDocument).ConfigureAwait(false);
return entity;
}

public Task<TEntity> UpdateAsync(TEntity entity)
public async Task<TDomain> DeleteAsync(TDomain entity)
{
throw new NotImplementedException();
var filter = Builders<TDocument>.Filter.Eq(e => e.ID, entity.Id.ToString());
await Collection.DeleteOneAsync(filter).ConfigureAwait(false);
return entity;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using AutoMapper;
using MongoDB.Driver;
using ReviewService.Domain.Entities;
using ReviewService.Domain.Repositories;
using ReviewService.Infrastructure.Repository.Documents;

namespace ReviewService.Infrastructure.Repository.Repositories;

public class ReviewRepository(IMongoDatabase mongoDatabase,IMapper mapper) : GenericRepository<ReviewDocument,Review>(mongoDatabase,mapper, "Reviews"), IReviewRepository
{
public async Task<IEnumerable<Review>> GetRecentReviewsForUsersAsync(IEnumerable<Guid> userIds, int count = 10)
{
var filter = Builders<ReviewDocument>.Filter.In(r => r.Author, userIds.Select(u => u.ToString()));
var result = await Collection
.Find(filter)
.SortByDescending(r => r.CreatedOn)
.Limit(count).ToCursorAsync().ConfigureAwait(false);
return Mapper.Map<IEnumerable<Review>>(result.ToEnumerable()) ?? throw new InvalidOperationException("No recent reviews found for the specified users.");
}

public async Task<IEnumerable<Review>> GetReviewsByDateRangeAsync(DateTime startDate, DateTime endDate)
{

var filter = Builders<ReviewDocument>.Filter.And(
Builders<ReviewDocument>.Filter.Gte(r => r.CreatedOn, startDate),
Builders<ReviewDocument>.Filter.Lte(r => r.CreatedOn, endDate)
);

if (startDate == DateTime.MinValue && endDate == DateTime.MaxValue)
{
filter = Builders<ReviewDocument>.Filter.Empty; // No date range filter
}

var result = await Collection
.Find(filter)
.ToCursorAsync()
.ConfigureAwait(false);

return Mapper.Map<IEnumerable<Review>>(result.ToEnumerable() ?? throw new InvalidOperationException("No reviews found in the specified date range."));
}

public async Task<IEnumerable<Review>> GetReviewsByMovieIdAsync(Guid movieId)
{
var filter = Builders<ReviewDocument>.Filter.Eq(r => r.MovieId, movieId);
var result = await Collection
.Find(filter)
.ToCursorAsync().ConfigureAwait(false);

return Mapper.Map<IEnumerable<Review>>(result.ToEnumerable() ?? throw new InvalidOperationException("No reviews found for the specified movie."));
}

public async Task<IEnumerable<Review>> GetReviewsByRatingAsync(int rating)
{
var filter = Builders<ReviewDocument>.Filter.Eq(r => r.Rating, rating);
var result = await Collection
.Find(filter)
.ToCursorAsync()
.ConfigureAwait(false);

return Mapper.Map<IEnumerable<Review>>(result.ToEnumerable() ?? throw new InvalidOperationException("No reviews found with the specified rating."));
}

public async Task<IEnumerable<Review>> GetReviewsByUserIdAsync(Guid userId)
{
var filter = Builders<ReviewDocument>.Filter.Eq(r => r.Author, userId.ToString());
var result = await Collection
.Find(filter)
.ToCursorAsync()
.ConfigureAwait(false);

return Mapper.Map<IEnumerable<Review>>(result.ToEnumerable() ?? throw new InvalidOperationException("No reviews found for the specified user."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="MongoDB.Entities" Version="23.1.1" />
</ItemGroup>

Expand Down
Loading