From 86b9fe47599b5e1169e98dc4f81a20ba6a235fca Mon Sep 17 00:00:00 2001 From: eggwhat Date: Sat, 27 Apr 2024 00:58:05 +0200 Subject: [PATCH 01/19] (#30) move event service to more fitting directory --- .../MiniSpace.Services.Events.Infrastructure/Extensions.cs | 1 - .../Services}/EventService.cs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) rename MiniSpace.Services.Events/src/{MiniSpace.Services.Events.Application/Services/Events => MiniSpace.Services.Events.Infrastructure/Services}/EventService.cs (92%) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs index 82a642ba3..5dc4b405c 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs @@ -37,7 +37,6 @@ using MiniSpace.Services.Events.Application.Events.External; using MiniSpace.Services.Events.Application.Services; using MiniSpace.Services.Events.Application.Services.Clients; -using MiniSpace.Services.Events.Application.Services.Events; using MiniSpace.Services.Events.Core.Repositories; using MiniSpace.Services.Events.Infrastructure.Contexts; using MiniSpace.Services.Events.Infrastructure.Decorators; diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Events/EventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs similarity index 92% rename from MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Events/EventService.cs rename to MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs index d0e6d1ed7..843b240b0 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Events/EventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs @@ -2,13 +2,15 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using MiniSpace.Services.Events.Application; using MiniSpace.Services.Events.Application.Commands; using MiniSpace.Services.Events.Application.DTO; +using MiniSpace.Services.Events.Application.Services; using MiniSpace.Services.Events.Application.Wrappers; using MiniSpace.Services.Events.Core.Entities; using MiniSpace.Services.Events.Core.Repositories; -namespace MiniSpace.Services.Events.Application.Services.Events +namespace MiniSpace.Services.Events.Infrastructure.Services { public class EventService : IEventService { From 2cf0055ad5945dfeff9090405b89ad2c82dd2921 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Sat, 27 Apr 2024 01:01:33 +0200 Subject: [PATCH 02/19] (#30) update default sorting criteria --- .../Mongo/Repositories/Extensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index 17ec0605f..60b52a48c 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -97,7 +97,7 @@ public static SortDefinition ToSortDefinition(IEnumerable var sort = sortByArguments.ToList(); if(!sort.Any()) { - sort.Add("PublishDate"); + sort.Add("StartDate"); } var sortDefinitionBuilder = Builders.Sort; var sortDefinition = sort From 79c953e9d091c15ddd616328df7a01db0151f986 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Sat, 27 Apr 2024 01:16:48 +0200 Subject: [PATCH 03/19] (#30) fix issue with event service --- .../src/MiniSpace.Services.Events.Api/Program.cs | 2 +- .../Services/IEventService.cs | 2 +- .../Services/EventService.cs | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs index 082b1d68b..1c5c57439 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs @@ -36,7 +36,7 @@ public static async Task Main(string[] args) .Get("", ctx => ctx.Response.WriteAsync(ctx.RequestServices.GetService().Name)) .Post("events/search", async (cmd, ctx) => { - var pagedResult = await ctx.RequestServices.GetService().SignInAsync(cmd); + var pagedResult = await ctx.RequestServices.GetService().BrowseEventsAsync(cmd); await ctx.Response.WriteJsonAsync(pagedResult); })) .UseDispatcherEndpoints(endpoints => endpoints diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs index 5bde55989..09f101321 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs @@ -8,6 +8,6 @@ namespace MiniSpace.Services.Events.Application.Services { public interface IEventService { - Task>> SignInAsync(SearchEvents command); + Task>> BrowseEventsAsync(SearchEvents command); } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs index 843b240b0..9d09ee88e 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs @@ -25,17 +25,17 @@ public EventService(IEventRepository eventRepository, IEventValidator eventValid _appContext = appContext; } - public async Task>> SignInAsync(SearchEvents command) + public async Task>> BrowseEventsAsync(SearchEvents command) { - var dateTo = DateTime.MinValue; var dateFrom = DateTime.MinValue; - if(command.DateTo != string.Empty) + var dateTo = DateTime.MinValue; + if(command.DateFrom != string.Empty) { - _eventValidator.ParseDate(command.DateTo, "DateTo"); + dateFrom =_eventValidator.ParseDate(command.DateFrom, "DateFrom"); } - if(command.DateFrom != string.Empty) + if(command.DateTo != string.Empty) { - _eventValidator.ParseDate(command.DateFrom, "DateFrom"); + dateTo = _eventValidator.ParseDate(command.DateTo, "DateTo"); } (int pageNumber, int pageSize) = _eventValidator.PageFilter(command.Pageable.Page, command.Pageable.Size); From a245915a1eafc8c95803544528ece9d623c977a4 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 02:01:40 +0200 Subject: [PATCH 04/19] (#30) remove coorganizers field --- .../DTO/EventDto.cs | 2 -- .../Entities/Event.cs | 22 ++----------------- .../OrganizerAlreadyAddedException.cs | 14 ------------ .../Mongo/Documents/EventDocument.cs | 1 - .../Mongo/Documents/Extensions.cs | 4 +--- 5 files changed, 3 insertions(+), 40 deletions(-) delete mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Exceptions/OrganizerAlreadyAddedException.cs diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs index ebd042145..e1e6202e4 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs @@ -14,7 +14,6 @@ public class EventDto public OrganizerDto Organizer { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } - public IEnumerable CoOrganizers { get; set; } public AddressDto Location { get; set; } //public string Image { get; set; } public int InterestedStudents { get; set; } @@ -40,7 +39,6 @@ public EventDto(Event @event, Guid studentId) Organizer = new OrganizerDto(@event.Organizer); StartDate = @event.StartDate; EndDate = @event.EndDate; - CoOrganizers = @event.CoOrganizers.Select(x => new OrganizerDto(x)); Location = new AddressDto(@event.Location); InterestedStudents = @event.InterestedStudents.Count(); SignedUpStudents = @event.SignedUpStudents.Count(); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs index 61d620965..b303dd41e 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs @@ -8,7 +8,6 @@ namespace MiniSpace.Services.Events.Core.Entities { public class Event: AggregateRoot { - private ISet _coOrganizers = new HashSet(); private ISet _interestedStudents = new HashSet(); private ISet _signedUpStudents = new HashSet(); private ISet _ratings = new HashSet(); @@ -25,12 +24,6 @@ public class Event: AggregateRoot public State State { get; private set; } public DateTime PublishDate { get; private set; } - public IEnumerable CoOrganizers - { - get => _coOrganizers; - private set => _coOrganizers = new HashSet(value); - } - public IEnumerable InterestedStudents { get => _interestedStudents; @@ -51,7 +44,7 @@ public IEnumerable Ratings public Event(AggregateId id, string name, string description, DateTime startDate, DateTime endDate, Address location, int capacity, decimal fee, Category category, State state, DateTime publishDate, - Organizer organizer, IEnumerable coOrganizers = null, IEnumerable interestedStudents = null, + Organizer organizer, IEnumerable interestedStudents = null, IEnumerable signedUpStudents = null, IEnumerable ratings = null) { Id = id; @@ -65,7 +58,6 @@ public Event(AggregateId id, string name, string description, DateTime startDat Category = category; State = state; Organizer = organizer; - CoOrganizers = coOrganizers ?? Enumerable.Empty(); InterestedStudents = interestedStudents ?? Enumerable.Empty(); SignedUpStudents = signedUpStudents ?? Enumerable.Empty(); Ratings = ratings ?? Enumerable.Empty(); @@ -95,16 +87,6 @@ public void Update(string name, string description, DateTime startDate, DateTime PublishDate = publishDate; } - public void AddOrganizer(Organizer organizer) - { - if (CoOrganizers.Any(o => o.Id == organizer.Id)) - { - throw new OrganizerAlreadyAddedException(organizer.Id); - } - - _coOrganizers.Add(organizer); - } - public void SignUpStudent(Participant participant) { if (SignedUpStudents.Any(p => p.StudentId == participant.StudentId)) @@ -199,6 +181,6 @@ private void ChangeState(State state) } public bool IsOrganizer(Guid organizerId) - => Organizer.Id == organizerId || CoOrganizers.Any(o => o.Id == organizerId); + => Organizer.Id == organizerId; } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Exceptions/OrganizerAlreadyAddedException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Exceptions/OrganizerAlreadyAddedException.cs deleted file mode 100644 index 13bed5f20..000000000 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Exceptions/OrganizerAlreadyAddedException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace MiniSpace.Services.Events.Core.Exceptions -{ - public class OrganizerAlreadyAddedException : DomainException - { - public override string Code { get; } = "organizer_already_added"; - - public OrganizerAlreadyAddedException(Guid id) - : base($"Organizer with id: '{id}' has been already added") - { - } - } -} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs index 9c8c88738..5859b603a 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs @@ -14,7 +14,6 @@ public class EventDocument : IIdentifiable public Organizer Organizer { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } - public IEnumerable CoOrganizers { get; set; } public Address Location { get; set; } //public string Image { get; set; } public IEnumerable InterestedStudents { get; set; } diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs index 4e4aa768a..8c288b5b9 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs @@ -16,7 +16,6 @@ public static EventDto AsDto(this EventDocument document, Guid studentId) Organizer = document.Organizer.AsDto(), StartDate = document.StartDate, EndDate = document.EndDate, - CoOrganizers = document.CoOrganizers.Select(x => x.AsDto()), Location = document.Location.AsDto(), InterestedStudents = document.InterestedStudents.Count(), SignedUpStudents = document.SignedUpStudents.Count(), @@ -33,7 +32,7 @@ public static EventDto AsDto(this EventDocument document, Guid studentId) public static Event AsEntity(this EventDocument document) => new (document.Id, document.Name, document.Description, document.StartDate, document.EndDate, document.Location, document.Capacity, document.Fee, document.Category, document.State, document.PublishDate, - document.Organizer, document.CoOrganizers, document.InterestedStudents, document.SignedUpStudents, document.Ratings); + document.Organizer, document.InterestedStudents, document.SignedUpStudents, document.Ratings); public static EventDocument AsDocument(this Event entity) => new () @@ -45,7 +44,6 @@ public static EventDocument AsDocument(this Event entity) StartDate = entity.StartDate, EndDate = entity.EndDate, Location = entity.Location, - CoOrganizers = entity.CoOrganizers, InterestedStudents = entity.InterestedStudents, SignedUpStudents = entity.SignedUpStudents, Capacity = entity.Capacity, From 78a7f6d6fa13ea99e7154df139f4ac29ada37f69 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 09:57:26 +0200 Subject: [PATCH 05/19] (#30) update background worker synchronization --- .../Services/Workers/EventStateUpdaterWorker.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Workers/EventStateUpdaterWorker.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Workers/EventStateUpdaterWorker.cs index 771061fcd..32137f273 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Workers/EventStateUpdaterWorker.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Workers/EventStateUpdaterWorker.cs @@ -16,6 +16,7 @@ public class EventStateUpdaterWorker: BackgroundService private readonly IMessageBroker _messageBroker; private readonly ICommandDispatcher _commandDispatcher; private readonly IDateTimeProvider _dateTimeProvider; + private const int MinutesInterval = 5; public EventStateUpdaterWorker(IMessageBroker messageBroker, ICommandDispatcher commandDispatcher, IDateTimeProvider dateTimeProvider) @@ -34,12 +35,13 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var now = _dateTimeProvider.Now; var minutes = now.Minute; - if (minutes % 10 == 0) + if (minutes % MinutesInterval == 0) { await _commandDispatcher.SendAsync(new UpdateEventsState(now), stoppingToken); } - var nextTime = now.AddMinutes(10 - (minutes % 10)); + var nextTime = now.AddMinutes(MinutesInterval - (minutes % MinutesInterval)).AddSeconds(-now.Second) + .AddMilliseconds(-now.Millisecond); var delay = nextTime - now; await Task.Delay(delay, stoppingToken); From 4986a780a2659b6552a44a86d4acc7d4f94917a0 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 10:43:34 +0200 Subject: [PATCH 06/19] (#30) update organizer entity --- .../Commands/AddEvent.cs | 8 +++++--- .../Commands/Handlers/AddEventHandler.cs | 2 +- .../DTO/OrganizerDto.cs | 6 ++++-- .../MiniSpace.Services.Events.Core/Entities/Organizer.cs | 8 +++++--- .../Mongo/Documents/Extensions.cs | 3 ++- .../Mongo/Repositories/Extensions.cs | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/AddEvent.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/AddEvent.cs index cfb4d59ae..8573c7592 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/AddEvent.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/AddEvent.cs @@ -9,6 +9,7 @@ public class AddEvent : ICommand public Guid EventId { get; } public string Name { get; } public Guid OrganizerId { get; } + public Guid OrganizationId { get; } public string StartDate { get; } public string EndDate { get; } public string BuildingName { get; } @@ -23,13 +24,14 @@ public class AddEvent : ICommand public string Category { get; } public string PublishDate { get; } - public AddEvent(Guid eventId, string name, Guid organizerId, string startDate, string endDate, - string buildingName, string street, string buildingNumber, string apartmentNumber, string city, - string zipCode, string description, int capacity, decimal fee, string category, string publishDate) + public AddEvent(Guid eventId, string name, Guid organizerId, Guid organizationId, string startDate, + string endDate, string buildingName, string street, string buildingNumber, string apartmentNumber, + string city, string zipCode, string description, int capacity, decimal fee, string category, string publishDate) { EventId = eventId == Guid.Empty ? Guid.NewGuid() : eventId; Name = name; OrganizerId = organizerId; + OrganizationId = organizationId; StartDate = startDate; EndDate = endDate; BuildingName = buildingName; diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs index cc84f8a88..81f82a90e 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs @@ -62,7 +62,7 @@ public async Task HandleAsync(AddEvent command, CancellationToken cancellationTo state = State.ToBePublished; } - var organizer = new Organizer(command.OrganizerId, identity.Name, identity.Email, string.Empty); + var organizer = new Organizer(command.OrganizerId, identity.Name, identity.Email, command.OrganizerId, string.Empty); var @event = Event.Create(command.EventId, command.Name, command.Description, startDate, endDate, address, command.Capacity, command.Fee, category, state, publishDate, organizer); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizerDto.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizerDto.cs index bbdb13ef7..d7ee683d3 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizerDto.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizerDto.cs @@ -8,7 +8,8 @@ public class OrganizerDto public Guid Id { get; set; } public string Name { get; set; } public string Email { get; set; } - public string Organization { get; set; } + public Guid OrganizationId { get; set; } + public string OrganizationName { get; set; } public OrganizerDto() { @@ -19,7 +20,8 @@ public OrganizerDto(Organizer organizer) Id = organizer.Id; Name = organizer.Name; Email = organizer.Email; - Organization = organizer.Organization; + OrganizationId = organizer.OrganizationId; + OrganizationName = organizer.OrganizationName; } } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Organizer.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Organizer.cs index a2d988afa..1584b6870 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Organizer.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Organizer.cs @@ -7,14 +7,16 @@ public class Organizer public Guid Id { get; set; } public string Name { get; set; } public string Email { get; set; } - public string Organization { get; set; } + public Guid OrganizationId { get; set; } + public string OrganizationName { get; set; } - public Organizer(Guid id, string name, string email, string organization) + public Organizer(Guid id, string name, string email, Guid organizationId, string organizationName) { Id = id; Name = name; Email = email; - Organization = organization; + OrganizationId = organizationId; + OrganizationName = organizationName; } } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs index 8c288b5b9..ca2849c85 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs @@ -74,7 +74,8 @@ public static OrganizerDto AsDto(this Organizer entity) Id = entity.Id, Name = entity.Name, Email = entity.Email, - Organization = entity.Organization + OrganizationId = entity.OrganizationId, + OrganizationName = entity.OrganizationName }; public static StudentDocument AsDocument(this Student entity) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index 60b52a48c..20008d4f0 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -70,7 +70,7 @@ public static FilterDefinition ToFilterDefinition(string name, st if (!string.IsNullOrWhiteSpace(organizer)) { - filterDefinition &= filterDefinitionBuilder.Regex(x => x.Organizer.Name, + filterDefinition &= filterDefinitionBuilder.Regex(x => x.Organizer.OrganizationName, new BsonRegularExpression(new Regex($".*{organizer}.*", RegexOptions.IgnoreCase))); } From c04fb4467ed56560513530ee975f023f7134c834 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 14:00:44 +0200 Subject: [PATCH 07/19] (#30) add endpoint for getting organizer events --- .../MiniSpace.Services.Events.Api/Program.cs | 6 ++- .../Commands/SearchOrganizerEvents.cs | 16 ++++++++ .../Exceptions/InvalidEventStateException.cs | 15 ++++++++ ...cs => UnauthorizedEventAccessException.cs} | 0 ...uthorizedOrganizerEventsAccessException.cs | 18 +++++++++ .../Services/IEventService.cs | 1 + .../Services/IEventValidator.cs | 1 + .../Repositories/IEventRepository.cs | 4 +- .../Handlers/GetStudentEventsHandler.cs | 2 +- .../Repositories/EventMongoRepository.cs | 37 ++++++++++++++++--- .../Mongo/Repositories/Extensions.cs | 19 +++++++++- .../Services/EventService.cs | 37 ++++++++++++++++++- .../Services/EventValidator.cs | 9 +++++ 13 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchOrganizerEvents.cs create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventStateException.cs rename MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/{UnauthorizedEventAccesException.cs => UnauthorizedEventAccessException.cs} (100%) create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedOrganizerEventsAccessException.cs diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs index 1c5c57439..2745c41d6 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/Program.cs @@ -38,10 +38,14 @@ public static async Task Main(string[] args) { var pagedResult = await ctx.RequestServices.GetService().BrowseEventsAsync(cmd); await ctx.Response.WriteJsonAsync(pagedResult); + }) + .Post("events/search/organizer", async (cmd, ctx) => + { + var pagedResult = await ctx.RequestServices.GetService().BrowseOrganizerEventsAsync(cmd); + await ctx.Response.WriteJsonAsync(pagedResult); })) .UseDispatcherEndpoints(endpoints => endpoints .Get("events/{eventId}") - //.Get>("events/organizer/{organizerId}") .Put("events/{eventId}") .Post("events", afterDispatch: (cmd, ctx) => ctx.Response.Created($"events/{cmd.EventId}")) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchOrganizerEvents.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchOrganizerEvents.cs new file mode 100644 index 000000000..e51c824fd --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchOrganizerEvents.cs @@ -0,0 +1,16 @@ +using System; +using Convey.CQRS.Commands; +using MiniSpace.Services.Events.Application.DTO; + +namespace MiniSpace.Services.Events.Application.Commands +{ + public class SearchOrganizerEvents : ICommand + { + public string Name { get; set; } + public Guid OrganizerId { get; set; } + public string DateFrom { get; set; } + public string DateTo { get; set; } + public string State { get; set; } + public PageableDto Pageable { get; set; } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventStateException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventStateException.cs new file mode 100644 index 000000000..ca4f6b106 --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventStateException.cs @@ -0,0 +1,15 @@ +using System; + +namespace MiniSpace.Services.Events.Application.Exceptions +{ + public class InvalidEventStateException : AppException + { + public override string Code { get; } = "invalid_event_state"; + public string State { get; } + + public InvalidEventStateException(string state) : base($"Event State property is invalid: {state}.") + { + State = state; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedEventAccesException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedEventAccessException.cs similarity index 100% rename from MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedEventAccesException.cs rename to MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedEventAccessException.cs diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedOrganizerEventsAccessException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedOrganizerEventsAccessException.cs new file mode 100644 index 000000000..a542aadef --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/UnauthorizedOrganizerEventsAccessException.cs @@ -0,0 +1,18 @@ +using System; + +namespace MiniSpace.Services.Events.Application.Exceptions +{ + public class UnauthorizedOrganizerEventsAccessException : AppException + { + public override string Code { get; } = "unauthorized_event_access"; + public Guid OrganizerId { get; } + public Guid UserId { get; } + + public UnauthorizedOrganizerEventsAccessException(Guid organizerId, Guid userId) + : base($"Unauthorized access to organizer events with ID: '{organizerId}' by user with ID: '{userId}'.") + { + OrganizerId = organizerId; + UserId = userId; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs index 09f101321..7a3a9429c 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventService.cs @@ -9,5 +9,6 @@ namespace MiniSpace.Services.Events.Application.Services public interface IEventService { Task>> BrowseEventsAsync(SearchEvents command); + Task>> BrowseOrganizerEventsAsync(SearchOrganizerEvents command); } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs index fa494073e..a62f86949 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs @@ -7,6 +7,7 @@ public interface IEventValidator { Category ParseCategory(string categoryString); DateTime ParseDate(string dateString, string fieldName); + State ParseState(string stateString); void ValidateDates(DateTime earlierDate, DateTime laterDate, string earlierDateString, string endDateString); (int pageNumber, int pageSize) PageFilter(int pageNumber, int pageSize); void ValidateRequiredField(string fieldValue, string fieldName); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs index 41d28e0f3..fd7cde9c8 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs @@ -13,8 +13,10 @@ public interface IEventRepository Task AddAsync(Event @event); Task UpdateAsync(Event @event); Task DeleteAsync(Guid id); - Task,int,int,int,int>> BrowseAsync(int pageNumber, int pageSize, string name, + Task,int,int,int,int>> BrowseEventsAsync(int pageNumber, int pageSize, string name, string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State state, IEnumerable eventIds = null); + Task,int,int,int,int>> BrowseOrganizerEventsAsync(int pageNumber, int pageSize, string name, + Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State? state); } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs index ead1668e3..c88e3c0f0 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs @@ -43,7 +43,7 @@ public async Task>> HandleAsync(GetStudentEv var studentEvents = await _studentsServiceClient.GetAsync(query.StudentId); var studentEventIds = studentEvents.InterestedInEvents.Union(studentEvents.SignedUpEvents).ToList(); - var result = await _eventRepository.BrowseAsync(1, query.NumberOfResults, + var result = await _eventRepository.BrowseEventsAsync(1, query.NumberOfResults, string.Empty, string.Empty, DateTime.MinValue, DateTime.MinValue, Enumerable.Empty(), "asc", State.Published, studentEventIds); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs index 2fda11c8e..11a71201d 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs @@ -37,18 +37,43 @@ public async Task> GetAllAsync() return filteredEvents.Select(e => e.AsEntity()); } - public async Task,int,int,int,int>> BrowseAsync(int pageNumber, int pageSize, string name, string organizer, - DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State state, - IEnumerable eventIds = null) + private async Task<(int totalPages, int totalElements, IEnumerable data)> BrowseAsync( + FilterDefinition filterDefinition, SortDefinition sortDefinition, + int pageNumber, int pageSize) { - var filterDefinition = Repositories.Extensions.ToFilterDefinition(name, organizer, dateFrom, dateTo, state, eventIds); - var sortDefinition = Repositories.Extensions.ToSortDefinition(sortBy, direction); - var pagedEvents = await _repository.Collection.AggregateByPage( filterDefinition, sortDefinition, pageNumber, pageSize); + + return pagedEvents; + } + + public async Task,int,int,int,int>> BrowseEventsAsync(int pageNumber, int pageSize, + string name, string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, + string direction, State state, IEnumerable eventIds = null) + { + var filterDefinition = Repositories.Extensions.ToFilterDefinition(name, organizer, dateFrom, dateTo, eventIds); + filterDefinition.AddStateFilter(State.Published); + var sortDefinition = Repositories.Extensions.ToSortDefinition(sortBy, direction); + + var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); + + return new Tuple,int,int,int,int>(pagedEvents.data.Select(e => e.AsEntity()), + pageNumber, pageSize, pagedEvents.totalPages, pagedEvents.totalElements); + } + + public async Task,int,int,int,int>> BrowseOrganizerEventsAsync(int pageNumber, + int pageSize, string name, Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, + string direction, State? state) + { + var filterDefinition = Extensions.ToFilterDefinition(name, string.Empty, dateFrom, dateTo); + filterDefinition.AddOrganizerIdFilter(organizerId); + filterDefinition.AddStateFilter(state); + var sortDefinition = Extensions.ToSortDefinition(sortBy, direction); + + var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); return new Tuple,int,int,int,int>(pagedEvents.data.Select(e => e.AsEntity()), pageNumber, pageSize, pagedEvents.totalPages, pagedEvents.totalElements); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index 20008d4f0..9ed42e2a4 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -56,11 +56,10 @@ public static class Extensions } public static FilterDefinition ToFilterDefinition(string name, string organizer, - DateTime dateFrom, DateTime dateTo, State state, IEnumerable eventIds = null) + DateTime dateFrom, DateTime dateTo, IEnumerable eventIds = null) { var filterDefinitionBuilder = Builders.Filter; var filterDefinition = filterDefinitionBuilder.Empty; - filterDefinition &= filterDefinitionBuilder.Eq(x => x.State, state); if (!string.IsNullOrWhiteSpace(name)) { @@ -92,6 +91,22 @@ public static FilterDefinition ToFilterDefinition(string name, st return filterDefinition; } + public static void AddOrganizerIdFilter (this FilterDefinition filterDefinition, Guid organizerId) + { + var filterDefinitionBuilder = Builders.Filter; + filterDefinition &= filterDefinitionBuilder.Eq(x => x.Organizer.Id, organizerId); + } + + public static void AddStateFilter (this FilterDefinition filterDefinition, State? state) + { + if (state == null) + { + return; + } + var filterDefinitionBuilder = Builders.Filter; + filterDefinition &= filterDefinitionBuilder.Eq(x => x.State, state); + } + public static SortDefinition ToSortDefinition(IEnumerable sortByArguments, string direction) { var sort = sortByArguments.ToList(); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs index 9d09ee88e..c898a5a49 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs @@ -5,6 +5,7 @@ using MiniSpace.Services.Events.Application; using MiniSpace.Services.Events.Application.Commands; using MiniSpace.Services.Events.Application.DTO; +using MiniSpace.Services.Events.Application.Exceptions; using MiniSpace.Services.Events.Application.Services; using MiniSpace.Services.Events.Application.Wrappers; using MiniSpace.Services.Events.Core.Entities; @@ -39,7 +40,7 @@ public async Task>> BrowseEventsAsync(Search } (int pageNumber, int pageSize) = _eventValidator.PageFilter(command.Pageable.Page, command.Pageable.Size); - var result = await _eventRepository.BrowseAsync( + var result = await _eventRepository.BrowseEventsAsync( pageNumber, pageSize, command.Name, command.Organizer, dateFrom, dateTo, command.Pageable.Sort.SortBy, command.Pageable.Sort.Direction, State.Published); @@ -49,5 +50,39 @@ public async Task>> BrowseEventsAsync(Search return pagedEvents; } + + public async Task>> BrowseOrganizerEventsAsync(SearchOrganizerEvents command) + { + var identity = _appContext.Identity; + if(identity.IsAuthenticated && identity.Id != command.OrganizerId && !identity.IsAdmin) + { + throw new UnauthorizedOrganizerEventsAccessException(command.OrganizerId, identity.Id); + } + var dateFrom = DateTime.MinValue; + var dateTo = DateTime.MinValue; + State? state = null; + if(command.DateFrom != string.Empty) + { + dateFrom =_eventValidator.ParseDate(command.DateFrom, "DateFrom"); + } + if(command.DateTo != string.Empty) + { + dateTo = _eventValidator.ParseDate(command.DateTo, "DateTo"); + } + if(command.State != string.Empty) + { + state = _eventValidator.ParseState(command.State); + } + (int pageNumber, int pageSize) = _eventValidator.PageFilter(command.Pageable.Page, command.Pageable.Size); + + var result = await _eventRepository.BrowseOrganizerEventsAsync( + pageNumber, pageSize, command.Name, command.OrganizerId, dateFrom, dateTo, + command.Pageable.Sort.SortBy, command.Pageable.Sort.Direction, state); + + var pagedEvents = new PagedResponse>(result.Item1.Select(e => new EventDto(e, _appContext.Identity.Id)), + result.Item2, result.Item3, result.Item4, result.Item5); + + return pagedEvents; + } } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs index 301f67527..90fc335b3 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs @@ -28,6 +28,15 @@ public DateTime ParseDate(string dateString, string fieldName) } return date; } + + public State ParseState(string stateString) + { + if (!Enum.TryParse(stateString, true, out var state)) + { + throw new InvalidEventStateException(stateString); + } + return state; + } public void ValidateDates(DateTime earlierDate, DateTime laterDate, string earlierDateField, string laterDateField) { From 3324214cc3d94b57aca0af516098c67feaf3218e Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 14:13:11 +0200 Subject: [PATCH 08/19] (#30) update tuple return type --- .../Repositories/IEventRepository.cs | 11 ++++++----- .../Mongo/Repositories/EventMongoRepository.cs | 14 +++++++------- .../Services/EventService.cs | 10 +++++----- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs index fd7cde9c8..d2ee7507f 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs @@ -13,10 +13,11 @@ public interface IEventRepository Task AddAsync(Event @event); Task UpdateAsync(Event @event); Task DeleteAsync(Guid id); - Task,int,int,int,int>> BrowseEventsAsync(int pageNumber, int pageSize, string name, - string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, - State state, IEnumerable eventIds = null); - Task,int,int,int,int>> BrowseOrganizerEventsAsync(int pageNumber, int pageSize, string name, - Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State? state); + Task<(IEnumerable events, int pageNumber,int pageSize, int totalPages, int totalElements)> BrowseEventsAsync( + int pageNumber, int pageSize, string name, string organizer, DateTime dateFrom, DateTime dateTo, + IEnumerable sortBy, string direction, IEnumerable eventIds = null); + Task<(IEnumerable events, int pageNumber,int pageSize, int totalPages, int totalElements)> BrowseOrganizerEventsAsync( + int pageNumber, int pageSize, string name, Guid organizerId, DateTime dateFrom, DateTime dateTo, + IEnumerable sortBy, string direction, State? state); } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs index 11a71201d..9936754f4 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs @@ -50,9 +50,9 @@ public async Task> GetAllAsync() return pagedEvents; } - public async Task,int,int,int,int>> BrowseEventsAsync(int pageNumber, int pageSize, + public async Task<(IEnumerable events, int pageNumber,int pageSize, int totalPages, int totalElements)> BrowseEventsAsync(int pageNumber, int pageSize, string name, string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, - string direction, State state, IEnumerable eventIds = null) + string direction, IEnumerable eventIds = null) { var filterDefinition = Repositories.Extensions.ToFilterDefinition(name, organizer, dateFrom, dateTo, eventIds); filterDefinition.AddStateFilter(State.Published); @@ -60,11 +60,11 @@ public async Task,int,int,int,int>> BrowseEventsAsync(i var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); - return new Tuple,int,int,int,int>(pagedEvents.data.Select(e => e.AsEntity()), - pageNumber, pageSize, pagedEvents.totalPages, pagedEvents.totalElements); + return (pagedEvents.data.Select(e => e.AsEntity()), pageNumber, pageSize, + pagedEvents.totalPages, pagedEvents.totalElements); } - public async Task,int,int,int,int>> BrowseOrganizerEventsAsync(int pageNumber, + public async Task<(IEnumerable events, int pageNumber, int pageSize, int totalPages, int totalElements)> BrowseOrganizerEventsAsync(int pageNumber, int pageSize, string name, Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State? state) { @@ -75,8 +75,8 @@ public async Task,int,int,int,int>> BrowseOrganizerEven var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); - return new Tuple,int,int,int,int>(pagedEvents.data.Select(e => e.AsEntity()), - pageNumber, pageSize, pagedEvents.totalPages, pagedEvents.totalElements); + return (pagedEvents.data.Select(e => e.AsEntity()), pageNumber, pageSize, + pagedEvents.totalPages, pagedEvents.totalElements); } public Task AddAsync(Event @event) => _repository.AddAsync(@event.AsDocument()); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs index c898a5a49..9e65c0c36 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs @@ -42,11 +42,11 @@ public async Task>> BrowseEventsAsync(Search var result = await _eventRepository.BrowseEventsAsync( pageNumber, pageSize, command.Name, command.Organizer, dateFrom, dateTo, - command.Pageable.Sort.SortBy, command.Pageable.Sort.Direction, State.Published); + command.Pageable.Sort.SortBy, command.Pageable.Sort.Direction); var identity = _appContext.Identity; - var pagedEvents = new PagedResponse>(result.Item1.Select(e => new EventDto(e, identity.Id)), - result.Item2, result.Item3, result.Item4, result.Item5); + var pagedEvents = new PagedResponse>(result.events.Select(e => new EventDto(e, identity.Id)), + result.pageNumber, result.pageSize, result.totalPages, result.totalElements); return pagedEvents; } @@ -79,8 +79,8 @@ public async Task>> BrowseOrganizerEventsAsy pageNumber, pageSize, command.Name, command.OrganizerId, dateFrom, dateTo, command.Pageable.Sort.SortBy, command.Pageable.Sort.Direction, state); - var pagedEvents = new PagedResponse>(result.Item1.Select(e => new EventDto(e, _appContext.Identity.Id)), - result.Item2, result.Item3, result.Item4, result.Item5); + var pagedEvents = new PagedResponse>(result.events.Select(e => new EventDto(e, _appContext.Identity.Id)), + result.pageNumber, result.pageSize, result.totalPages, result.totalElements); return pagedEvents; } From 37345ac74b970577f739d44c18f854994da41870 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 15:12:01 +0200 Subject: [PATCH 09/19] (#30) update event repository for better clarity --- .../Handlers/GetStudentEventsHandler.cs | 2 +- .../Repositories/EventMongoRepository.cs | 5 ++- .../Mongo/Repositories/Extensions.cs | 37 ++++++++++--------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs index c88e3c0f0..85ea6d658 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs @@ -45,7 +45,7 @@ public async Task>> HandleAsync(GetStudentEv var result = await _eventRepository.BrowseEventsAsync(1, query.NumberOfResults, string.Empty, string.Empty, DateTime.MinValue, DateTime.MinValue, - Enumerable.Empty(), "asc", State.Published, studentEventIds); + Enumerable.Empty(), "asc", studentEventIds); return new PagedResponse>(result.Item1.Select(e => new EventDto(e, identity.Id)), result.Item2, result.Item3, result.Item4, result.Item5);; diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs index 9936754f4..0094b5fb3 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs @@ -54,7 +54,8 @@ public async Task> GetAllAsync() string name, string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, IEnumerable eventIds = null) { - var filterDefinition = Repositories.Extensions.ToFilterDefinition(name, organizer, dateFrom, dateTo, eventIds); + var filterDefinition = Repositories.Extensions.ToFilterDefinition(name, dateFrom, dateTo, eventIds); + filterDefinition.AddOrganizerNameFilter(organizer); filterDefinition.AddStateFilter(State.Published); var sortDefinition = Repositories.Extensions.ToSortDefinition(sortBy, direction); @@ -68,7 +69,7 @@ public async Task> GetAllAsync() int pageSize, string name, Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State? state) { - var filterDefinition = Extensions.ToFilterDefinition(name, string.Empty, dateFrom, dateTo); + var filterDefinition = Extensions.ToFilterDefinition(name, dateFrom, dateTo); filterDefinition.AddOrganizerIdFilter(organizerId); filterDefinition.AddStateFilter(state); var sortDefinition = Extensions.ToSortDefinition(sortBy, direction); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index 9ed42e2a4..c1d407972 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -13,6 +13,7 @@ namespace MiniSpace.Services.Events.Infrastructure.Mongo.Repositories { public static class Extensions { + private static readonly FilterDefinitionBuilder FilterDefinitionBuilder = Builders.Filter; public static async Task<(int totalPages, int totalElements, IReadOnlyList data)> AggregateByPage( this IMongoCollection collection, FilterDefinition filterDefinition, @@ -55,46 +56,47 @@ public static class Extensions return (totalPages, (int)count, data); } - public static FilterDefinition ToFilterDefinition(string name, string organizer, - DateTime dateFrom, DateTime dateTo, IEnumerable eventIds = null) + public static FilterDefinition ToFilterDefinition(string name, DateTime dateFrom, + DateTime dateTo, IEnumerable eventIds = null) { - var filterDefinitionBuilder = Builders.Filter; - var filterDefinition = filterDefinitionBuilder.Empty; + var filterDefinition = FilterDefinitionBuilder.Empty; if (!string.IsNullOrWhiteSpace(name)) { - filterDefinition &= filterDefinitionBuilder.Regex(x => x.Name, + filterDefinition &= FilterDefinitionBuilder.Regex(x => x.Name, new BsonRegularExpression(new Regex($".*{name}.*", RegexOptions.IgnoreCase))); } - if (!string.IsNullOrWhiteSpace(organizer)) - { - filterDefinition &= filterDefinitionBuilder.Regex(x => x.Organizer.OrganizationName, - new BsonRegularExpression(new Regex($".*{organizer}.*", RegexOptions.IgnoreCase))); - } - if (dateFrom != DateTime.MinValue) { - filterDefinition &= filterDefinitionBuilder.Gte(x => x.StartDate, dateFrom); + filterDefinition &= FilterDefinitionBuilder.Gte(x => x.StartDate, dateFrom); } if (dateTo != DateTime.MinValue) { - filterDefinition &= filterDefinitionBuilder.Lte(x => x.EndDate, dateTo); + filterDefinition &= FilterDefinitionBuilder.Lte(x => x.EndDate, dateTo); } if (eventIds != null) { - filterDefinition &= filterDefinitionBuilder.In(x => x.Id, eventIds); + filterDefinition &= FilterDefinitionBuilder.In(x => x.Id, eventIds); } return filterDefinition; } + public static void AddOrganizerNameFilter (this FilterDefinition filterDefinition, string organizer) + { + if (!string.IsNullOrWhiteSpace(organizer)) + { + filterDefinition &= FilterDefinitionBuilder.Regex(x => x.Organizer.OrganizationName, + new BsonRegularExpression(new Regex($".*{organizer}.*", RegexOptions.IgnoreCase))); + } + } + public static void AddOrganizerIdFilter (this FilterDefinition filterDefinition, Guid organizerId) { - var filterDefinitionBuilder = Builders.Filter; - filterDefinition &= filterDefinitionBuilder.Eq(x => x.Organizer.Id, organizerId); + filterDefinition &= FilterDefinitionBuilder.Eq(x => x.Organizer.Id, organizerId); } public static void AddStateFilter (this FilterDefinition filterDefinition, State? state) @@ -103,8 +105,7 @@ public static void AddStateFilter (this FilterDefinition filterDe { return; } - var filterDefinitionBuilder = Builders.Filter; - filterDefinition &= filterDefinitionBuilder.Eq(x => x.State, state); + filterDefinition &= FilterDefinitionBuilder.Eq(x => x.State, state); } public static SortDefinition ToSortDefinition(IEnumerable sortByArguments, string direction) From 2a807c6584ed4d9c0e7b3a8db5fb893654493bd6 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 15:52:57 +0200 Subject: [PATCH 10/19] (#30) update validation for fields name and description --- .../Commands/Handlers/AddEventHandler.cs | 4 ++-- .../Exceptions/EmptyRequiredEventFieldException.cs | 13 ------------- .../Exceptions/InvalidEventDescriptionException.cs | 13 +++++++++++++ .../Exceptions/InvalidEventNameException.cs | 13 +++++++++++++ .../Services/IEventValidator.cs | 3 ++- .../Services/EventValidator.cs | 12 +++++++++--- 6 files changed, 39 insertions(+), 19 deletions(-) delete mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/EmptyRequiredEventFieldException.cs create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventDescriptionException.cs create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventNameException.cs diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs index 81f82a90e..967d8b325 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs @@ -39,8 +39,8 @@ public async Task HandleAsync(AddEvent command, CancellationToken cancellationTo if(identity.Id != command.OrganizerId) throw new OrganizerCannotAddEventForAnotherOrganizerException(identity.Id, command.OrganizerId); - _eventValidator.ValidateRequiredField(command.Name, "event_name"); - _eventValidator.ValidateRequiredField(command.Description, "event_description"); + _eventValidator.ValidateName(command.Name); + _eventValidator.ValidateDescription(command.Description); var startDate = _eventValidator.ParseDate(command.StartDate, "event_start_date"); var endDate = _eventValidator.ParseDate(command.EndDate, "event_end_date"); var now = _dateTimeProvider.Now; diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/EmptyRequiredEventFieldException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/EmptyRequiredEventFieldException.cs deleted file mode 100644 index f5efc3d86..000000000 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/EmptyRequiredEventFieldException.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MiniSpace.Services.Events.Application.Exceptions -{ - public class EmptyRequiredEventFieldException : AppException - { - public override string Code { get; } = "required_event_field_empty"; - public string FieldName { get; } - - public EmptyRequiredEventFieldException(string fieldName) : base($"Required event field: `{fieldName}` is empty.") - { - FieldName = fieldName; - } - } -} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventDescriptionException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventDescriptionException.cs new file mode 100644 index 000000000..6934dbcb3 --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventDescriptionException.cs @@ -0,0 +1,13 @@ +namespace MiniSpace.Services.Events.Application.Exceptions +{ + public class InvalidEventDescriptionException : AppException + { + public override string Code { get; } = "invalid_event_description"; + public string Description { get; } + + public InvalidEventDescriptionException(string description): base("Invalid event description. It cannot be empty or longer than 5000 characters.") + { + Description = description; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventNameException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventNameException.cs new file mode 100644 index 000000000..c2db3eaee --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/InvalidEventNameException.cs @@ -0,0 +1,13 @@ +namespace MiniSpace.Services.Events.Application.Exceptions +{ + public class InvalidEventNameException : AppException + { + public override string Code { get; } = "invalid_event_name"; + public string Name { get; } + + public InvalidEventNameException(string name): base("Invalid event name. It cannot be empty or longer than 300 characters.") + { + Name = name; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs index a62f86949..29a8ee6c4 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/IEventValidator.cs @@ -10,7 +10,8 @@ public interface IEventValidator State ParseState(string stateString); void ValidateDates(DateTime earlierDate, DateTime laterDate, string earlierDateString, string endDateString); (int pageNumber, int pageSize) PageFilter(int pageNumber, int pageSize); - void ValidateRequiredField(string fieldValue, string fieldName); + void ValidateName(string name); + void ValidateDescription(string description); void ValidateCapacity(int capacity); void ValidateFee(decimal fee); void ValidateUpdatedCapacity(int currentCapacity, int newCapacity); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs index 90fc335b3..2bb44a590 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventValidator.cs @@ -52,10 +52,16 @@ public void ValidateDates(DateTime earlierDate, DateTime laterDate, string earl return (pageNumber, pageSize); } - public void ValidateRequiredField(string fieldValue, string fieldName) + public void ValidateName(string name) { - if (string.IsNullOrWhiteSpace(fieldValue)) - throw new EmptyRequiredEventFieldException(fieldName); + if (string.IsNullOrWhiteSpace(name) || name.Length > 300) + throw new InvalidEventNameException(name); + } + + public void ValidateDescription(string description) + { + if (string.IsNullOrWhiteSpace(description) || description.Length > 1000) + throw new InvalidEventDescriptionException(description); } public void ValidateCapacity(int capacity) From a5f81e6b75f9c8ca53b235a7cd284a6b06574995 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 16:15:22 +0200 Subject: [PATCH 11/19] (#30) fix issue with mongo filters --- .../Mongo/Repositories/EventMongoRepository.cs | 14 +++++++------- .../Mongo/Repositories/Extensions.cs | 17 +++++++++++------ .../Services/EventMapper.cs | 8 ++++---- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs index 0094b5fb3..fdb9577f7 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs @@ -54,10 +54,10 @@ public async Task> GetAllAsync() string name, string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, IEnumerable eventIds = null) { - var filterDefinition = Repositories.Extensions.ToFilterDefinition(name, dateFrom, dateTo, eventIds); - filterDefinition.AddOrganizerNameFilter(organizer); - filterDefinition.AddStateFilter(State.Published); - var sortDefinition = Repositories.Extensions.ToSortDefinition(sortBy, direction); + var filterDefinition = Extensions.ToFilterDefinition(name, dateFrom, dateTo, eventIds) + .AddOrganizerNameFilter(organizer) + .AddStateFilter(State.Published); + var sortDefinition = Extensions.ToSortDefinition(sortBy, direction); var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); @@ -69,9 +69,9 @@ public async Task> GetAllAsync() int pageSize, string name, Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State? state) { - var filterDefinition = Extensions.ToFilterDefinition(name, dateFrom, dateTo); - filterDefinition.AddOrganizerIdFilter(organizerId); - filterDefinition.AddStateFilter(state); + var filterDefinition = Extensions.ToFilterDefinition(name, dateFrom, dateTo) + .AddOrganizerIdFilter(organizerId) + .AddStateFilter(state); var sortDefinition = Extensions.ToSortDefinition(sortBy, direction); var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index c1d407972..7a2418261 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -85,27 +85,32 @@ public static FilterDefinition ToFilterDefinition(string name, Da return filterDefinition; } - public static void AddOrganizerNameFilter (this FilterDefinition filterDefinition, string organizer) + public static FilterDefinition AddOrganizerNameFilter ( + this FilterDefinition filterDefinition, string organizer) { if (!string.IsNullOrWhiteSpace(organizer)) { filterDefinition &= FilterDefinitionBuilder.Regex(x => x.Organizer.OrganizationName, new BsonRegularExpression(new Regex($".*{organizer}.*", RegexOptions.IgnoreCase))); } + + return filterDefinition; } - public static void AddOrganizerIdFilter (this FilterDefinition filterDefinition, Guid organizerId) + public static FilterDefinition AddOrganizerIdFilter (this FilterDefinition filterDefinition, Guid organizerId) { filterDefinition &= FilterDefinitionBuilder.Eq(x => x.Organizer.Id, organizerId); + return filterDefinition; } - public static void AddStateFilter (this FilterDefinition filterDefinition, State? state) + public static FilterDefinition AddStateFilter (this FilterDefinition filterDefinition, State? state) { - if (state == null) + if (state != null) { - return; + filterDefinition &= FilterDefinitionBuilder.Eq(x => x.State, state); } - filterDefinition &= FilterDefinitionBuilder.Eq(x => x.State, state); + + return filterDefinition; } public static SortDefinition ToSortDefinition(IEnumerable sortByArguments, string direction) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventMapper.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventMapper.cs index 38fe02a95..b96602bf5 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventMapper.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventMapper.cs @@ -14,10 +14,10 @@ public IEnumerable MapAll(IEnumerable events) public IEvent Map(IDomainEvent @event) { // TODO: update mapper - // switch (@event) - // { - // - // } + switch (@event) + { + + } return null; } From c7efabab6ff6b706f273cbe6710e211c244f9d7d Mon Sep 17 00:00:00 2001 From: eggwhat Date: Mon, 29 Apr 2024 16:23:38 +0200 Subject: [PATCH 12/19] (#30) fix nullref exception in mongo aggregation --- .../Mongo/Repositories/Extensions.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index 7a2418261..a29781cbc 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -47,7 +47,11 @@ public static class Extensions ?.FirstOrDefault() ?.Count; - var totalPages = (int)Math.Ceiling((double)count/ pageSize); + if (count == null) + { + return (0, 0, Array.Empty()); + } + var totalPages = (int)Math.Ceiling((double)count / pageSize); var data = aggregation.First() .Facets.First(x => x.Name == "data") From 331d8ccd7c1e3357937569fcd69ae52fa728baa4 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 12:24:28 +0200 Subject: [PATCH 13/19] (#87) add endpoint for getting organizers --- .../Program.cs | 1 + .../Dto/OrganizationDetailsDto.cs | 13 ++++++++++ .../Dto/OrganizerDto.cs | 14 ++++++++++ .../Queries/GetOrganizationDetails.cs | 10 +++++++ .../Mongo/Documents/Extensions.cs | 10 +++++++ .../Handlers/GetOrganizationDetailsHandler.cs | 26 +++++++++++++++++++ 6 files changed, 74 insertions(+) create mode 100644 MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs create mode 100644 MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs create mode 100644 MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Queries/GetOrganizationDetails.cs create mode 100644 MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Queries/Handlers/GetOrganizationDetailsHandler.cs diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Api/Program.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Api/Program.cs index a8ba10395..a2a623dda 100644 --- a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Api/Program.cs +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Api/Program.cs @@ -33,6 +33,7 @@ public static async Task Main(string[] args) .UseDispatcherEndpoints(endpoints => endpoints .Get("", ctx => ctx.Response.WriteAsync(ctx.RequestServices.GetService().Name)) .Get("organizations/{organizationId}") + .Get("organizations/{organizationId}/details") .Get>("organizations/organizer/{organizerId}") .Get>("organizations/root") .Get>("organizations/{organizationId}/children") diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs new file mode 100644 index 000000000..57eaeb6dd --- /dev/null +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs @@ -0,0 +1,13 @@ +using System.Collections; + +namespace MiniSpace.Services.Organizations.Application.DTO +{ + public class OrganizationDetailsDto + { + public Guid Id { get; set; } + public string Name { get; set; } + public Guid ParentId { get; set; } + public bool IsLeaf { get; set; } + public IEnumerable Organizers { get; set; } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs new file mode 100644 index 000000000..e66bb15ac --- /dev/null +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs @@ -0,0 +1,14 @@ +using MiniSpace.Services.Organizations.Core.Entities; + +namespace MiniSpace.Services.Organizations.Application.DTO +{ + public class OrganizerDto + { + public Guid Id { get; set; } + + public OrganizerDto(Organizer organizer) + { + Id = organizer.Id; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Queries/GetOrganizationDetails.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Queries/GetOrganizationDetails.cs new file mode 100644 index 000000000..46b266a07 --- /dev/null +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Queries/GetOrganizationDetails.cs @@ -0,0 +1,10 @@ +using Convey.CQRS.Queries; +using MiniSpace.Services.Organizations.Application.DTO; + +namespace MiniSpace.Services.Organizations.Application.Queries +{ + public class GetOrganizationDetails : IQuery + { + public Guid OrganizationId { get; set; } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs index 3a3d97380..3cf78d4e3 100644 --- a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs @@ -27,6 +27,16 @@ public static OrganizationDto AsDto(this OrganizationDocument document) IsLeaf = document.IsLeaf }; + public static OrganizationDetailsDto AsDetailsDto(this OrganizationDocument document) + => new OrganizationDetailsDto() + { + Id = document.Id, + Name = document.Name, + ParentId = document.ParentId, + IsLeaf = document.IsLeaf, + Organizers = document.Organizers.Select(x => new OrganizerDto(x)) + }; + public static Organizer AsEntity(this OrganizerDocument document) => new Organizer(document.Id); diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Queries/Handlers/GetOrganizationDetailsHandler.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Queries/Handlers/GetOrganizationDetailsHandler.cs new file mode 100644 index 000000000..dd249addd --- /dev/null +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Queries/Handlers/GetOrganizationDetailsHandler.cs @@ -0,0 +1,26 @@ +using Convey.CQRS.Queries; +using Convey.Persistence.MongoDB; +using MiniSpace.Services.Organizations.Application.DTO; +using MiniSpace.Services.Organizations.Application.Queries; +using MiniSpace.Services.Organizations.Infrastructure.Mongo.Documents; +using MongoDB.Driver; + +namespace MiniSpace.Services.Organizations.Infrastructure.Mongo.Queries.Handlers +{ + public class GetOrganizationDetailsHandler : IQueryHandler + { + private readonly IMongoRepository _repository; + + public GetOrganizationDetailsHandler(IMongoRepository repository) + { + _repository = repository; + } + + public async Task HandleAsync(GetOrganizationDetails query, CancellationToken cancellationToken) + { + var organization = await _repository.GetAsync(query.OrganizationId); + + return organization?.AsDetailsDto(); + } + } +} \ No newline at end of file From b5540e588a3c5d0e3279308bbc00b1b6d52f5d82 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 12:26:23 +0200 Subject: [PATCH 14/19] (#87) remove unnecessary dto --- .../Dto/OrganizationDetailsDto.cs | 2 +- .../Dto/OrganizerDto.cs | 14 -------------- .../Mongo/Documents/Extensions.cs | 2 +- 3 files changed, 2 insertions(+), 16 deletions(-) delete mode 100644 MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs index 57eaeb6dd..a25f6c34e 100644 --- a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizationDetailsDto.cs @@ -8,6 +8,6 @@ public class OrganizationDetailsDto public string Name { get; set; } public Guid ParentId { get; set; } public bool IsLeaf { get; set; } - public IEnumerable Organizers { get; set; } + public IEnumerable Organizers { get; set; } } } \ No newline at end of file diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs deleted file mode 100644 index e66bb15ac..000000000 --- a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Application/Dto/OrganizerDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using MiniSpace.Services.Organizations.Core.Entities; - -namespace MiniSpace.Services.Organizations.Application.DTO -{ - public class OrganizerDto - { - public Guid Id { get; set; } - - public OrganizerDto(Organizer organizer) - { - Id = organizer.Id; - } - } -} \ No newline at end of file diff --git a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs index 3cf78d4e3..6322ec5c9 100644 --- a/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs +++ b/MiniSpace.Services.Organizations/src/MiniSpace.Services.Organizations.Infrastructure/Mongo/Documents/Extensions.cs @@ -34,7 +34,7 @@ public static OrganizationDetailsDto AsDetailsDto(this OrganizationDocument docu Name = document.Name, ParentId = document.ParentId, IsLeaf = document.IsLeaf, - Organizers = document.Organizers.Select(x => new OrganizerDto(x)) + Organizers = document.Organizers.Select(x => x.Id) }; public static Organizer AsEntity(this OrganizerDocument document) From b8b2606d20aeedc3b1e6fa8040eea5f4e75df0d1 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 12:31:09 +0200 Subject: [PATCH 15/19] (#30) add service client to get organization details --- .../appsettings.local.json | 3 ++- .../DTO/OrganizationDto.cs | 12 ++++++++++ .../Clients/IOrganizationsServiceClient.cs | 11 +++++++++ .../Extensions.cs | 1 + .../Services/OrganizationsServiceClient.cs | 24 +++++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizationDto.cs create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Clients/IOrganizationsServiceClient.cs create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/appsettings.local.json b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/appsettings.local.json index 187d80747..29f0f005f 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/appsettings.local.json +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Api/appsettings.local.json @@ -24,7 +24,8 @@ "type": "direct", "retries": 3, "services": { - "students": "http://localhost:5007" + "students": "http://localhost:5007", + "organizations": "http://localhost:5015" }, "requestMasking": { "enabled": true, diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizationDto.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizationDto.cs new file mode 100644 index 000000000..9a51e510d --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/OrganizationDto.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace MiniSpace.Services.Events.Application.DTO +{ + public class OrganizationDto + { + public Guid Id { get; set; } + public string Name { get; set; } + public IEnumerable Organizers; + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Clients/IOrganizationsServiceClient.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Clients/IOrganizationsServiceClient.cs new file mode 100644 index 000000000..49d592182 --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Services/Clients/IOrganizationsServiceClient.cs @@ -0,0 +1,11 @@ +using System; +using System.Threading.Tasks; +using MiniSpace.Services.Events.Application.DTO; + +namespace MiniSpace.Services.Events.Application.Services.Clients +{ + public interface IOrganizationsServiceClient + { + Task GetAsync(Guid id); + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs index 5dc4b405c..2aa4fe157 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Extensions.cs @@ -64,6 +64,7 @@ public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder) builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(ctx => ctx.GetRequiredService().Create()); builder.Services.TryDecorate(typeof(ICommandHandler<>), typeof(OutboxCommandHandlerDecorator<>)); builder.Services.TryDecorate(typeof(IEventHandler<>), typeof(OutboxEventHandlerDecorator<>)); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs new file mode 100644 index 000000000..883076eda --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; +using Convey.HTTP; +using MiniSpace.Services.Events.Application.DTO; +using MiniSpace.Services.Events.Application.Services.Clients; + +namespace MiniSpace.Services.Events.Infrastructure.Services +{ + public class OrganizationsServiceClient : IOrganizationsServiceClient + { + private readonly IHttpClient _httpClient; + private readonly string _url; + + public OrganizationsServiceClient(IHttpClient httpClient, HttpClientOptions options) + { + _httpClient = httpClient; + _url = options.Services["organizations"]; + } + + public Task GetAsync(Guid id) + => _httpClient.GetAsync($"{_url}/organizations/{id}/details"); + + } +} \ No newline at end of file From 690d1993dd636df44c3210c393acf84aa31e1400 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 12:37:17 +0200 Subject: [PATCH 16/19] (#30) add organizer-organization validation --- .../Commands/Handlers/AddEventHandler.cs | 21 +++++++++++++++---- .../OrganizationNotFoundException.cs | 15 +++++++++++++ ...zerDoesNotBelongToOrganizationException.cs | 18 ++++++++++++++++ .../OrganizationsServiceClient.cs | 2 +- 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizationNotFoundException.cs create mode 100644 MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizerDoesNotBelongToOrganizationException.cs rename MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/{ => Clients}/OrganizationsServiceClient.cs (91%) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs index 967d8b325..e767250a2 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs @@ -6,6 +6,7 @@ using MiniSpace.Services.Events.Application.Events; using MiniSpace.Services.Events.Application.Exceptions; using MiniSpace.Services.Events.Application.Services; +using MiniSpace.Services.Events.Application.Services.Clients; using MiniSpace.Services.Events.Core.Entities; using MiniSpace.Services.Events.Core.Repositories; @@ -15,17 +16,18 @@ public class AddEventHandler: ICommandHandler { private readonly IEventRepository _eventRepository; private readonly IMessageBroker _messageBroker; - private readonly IEventMapper _eventMapper; + private readonly IOrganizationsServiceClient _organizationsServiceClient; private readonly IDateTimeProvider _dateTimeProvider; private readonly IEventValidator _eventValidator; private readonly IAppContext _appContext; - public AddEventHandler(IEventRepository eventRepository, IMessageBroker messageBroker, IEventMapper eventMapper, - IDateTimeProvider dateTimeProvider, IEventValidator eventValidator, IAppContext appContext) + public AddEventHandler(IEventRepository eventRepository, IMessageBroker messageBroker, + IOrganizationsServiceClient organizationsServiceClient, IDateTimeProvider dateTimeProvider, + IEventValidator eventValidator, IAppContext appContext) { _eventRepository = eventRepository; _messageBroker = messageBroker; - _eventMapper = eventMapper; + _organizationsServiceClient = organizationsServiceClient; _dateTimeProvider = dateTimeProvider; _eventValidator = eventValidator; _appContext = appContext; @@ -62,6 +64,17 @@ public async Task HandleAsync(AddEvent command, CancellationToken cancellationTo state = State.ToBePublished; } + var organization = await _organizationsServiceClient.GetAsync(command.OrganizationId); + if (organization == null) + { + throw new OrganizationNotFoundException(command.OrganizationId); + } + + if (!organization.Organizers.Contains(command.OrganizerId)) + { + throw new OrganizerDoesNotBelongToOrganizationException(command.OrganizerId, command.OrganizationId); + } + var organizer = new Organizer(command.OrganizerId, identity.Name, identity.Email, command.OrganizerId, string.Empty); var @event = Event.Create(command.EventId, command.Name, command.Description, startDate, endDate, address, command.Capacity, command.Fee, category, state, publishDate, organizer); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizationNotFoundException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizationNotFoundException.cs new file mode 100644 index 000000000..83e7bb79a --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizationNotFoundException.cs @@ -0,0 +1,15 @@ +using System; + +namespace MiniSpace.Services.Events.Application.Exceptions +{ + public class OrganizationNotFoundException: AppException + { + public override string Code { get; } = "organization_not_found"; + public Guid OrganizationId { get; } + + public OrganizationNotFoundException(Guid organizationId): base($"Organization with id: '{organizationId}' was not found.") + { + OrganizationId = organizationId; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizerDoesNotBelongToOrganizationException.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizerDoesNotBelongToOrganizationException.cs new file mode 100644 index 000000000..7e5388802 --- /dev/null +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Exceptions/OrganizerDoesNotBelongToOrganizationException.cs @@ -0,0 +1,18 @@ +using System; + +namespace MiniSpace.Services.Events.Application.Exceptions +{ + public class OrganizerDoesNotBelongToOrganizationException : AppException + { + public override string Code => "organizer_does_not_belong_to_organization"; + public Guid OrganizerId { get; } + public Guid OrganizationId { get; } + + public OrganizerDoesNotBelongToOrganizationException(Guid organizerId, Guid organizationId) + : base($"Organizer with ID: {organizerId} does not belong to organization with ID: {organizationId}.") + { + OrganizerId = organizerId; + OrganizationId = organizationId; + } + } +} \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Clients/OrganizationsServiceClient.cs similarity index 91% rename from MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs rename to MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Clients/OrganizationsServiceClient.cs index 883076eda..60d490d8f 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/OrganizationsServiceClient.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/Clients/OrganizationsServiceClient.cs @@ -4,7 +4,7 @@ using MiniSpace.Services.Events.Application.DTO; using MiniSpace.Services.Events.Application.Services.Clients; -namespace MiniSpace.Services.Events.Infrastructure.Services +namespace MiniSpace.Services.Events.Infrastructure.Services.Clients { public class OrganizationsServiceClient : IOrganizationsServiceClient { From a4dbe8103d4eb9a22d3164e9e3d6c70f6359ca0a Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 12:56:11 +0200 Subject: [PATCH 17/19] (#30) add new search criteria: state and category --- .../Commands/SearchEvents.cs | 2 ++ .../Repositories/IEventRepository.cs | 2 +- .../Handlers/GetStudentEventsHandler.cs | 2 +- .../Repositories/EventMongoRepository.cs | 7 ++--- .../Mongo/Repositories/Extensions.cs | 27 ++++++++++++++++++- .../Services/EventService.cs | 13 ++++++++- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchEvents.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchEvents.cs index 1b9ef6791..c733a754a 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchEvents.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/SearchEvents.cs @@ -7,6 +7,8 @@ public class SearchEvents : ICommand { public string Name { get; set; } public string Organizer { get; set; } + public string Category { get; set; } + public string State { get; set; } public string DateFrom { get; set; } public string DateTo { get; set; } public PageableDto Pageable { get; set; } diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs index d2ee7507f..dd806a444 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Repositories/IEventRepository.cs @@ -15,7 +15,7 @@ public interface IEventRepository Task DeleteAsync(Guid id); Task<(IEnumerable events, int pageNumber,int pageSize, int totalPages, int totalElements)> BrowseEventsAsync( int pageNumber, int pageSize, string name, string organizer, DateTime dateFrom, DateTime dateTo, - IEnumerable sortBy, string direction, IEnumerable eventIds = null); + Category? category, State? state, IEnumerable sortBy, string direction, IEnumerable eventIds = null); Task<(IEnumerable events, int pageNumber,int pageSize, int totalPages, int totalElements)> BrowseOrganizerEventsAsync( int pageNumber, int pageSize, string name, Guid organizerId, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, string direction, State? state); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs index 85ea6d658..569bd96bd 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Queries/Handlers/GetStudentEventsHandler.cs @@ -44,7 +44,7 @@ public async Task>> HandleAsync(GetStudentEv var studentEventIds = studentEvents.InterestedInEvents.Union(studentEvents.SignedUpEvents).ToList(); var result = await _eventRepository.BrowseEventsAsync(1, query.NumberOfResults, - string.Empty, string.Empty, DateTime.MinValue, DateTime.MinValue, + string.Empty, string.Empty, DateTime.MinValue, DateTime.MinValue, null, null, Enumerable.Empty(), "asc", studentEventIds); return new PagedResponse>(result.Item1.Select(e => new EventDto(e, identity.Id)), diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs index fdb9577f7..e7c590173 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/EventMongoRepository.cs @@ -51,12 +51,13 @@ public async Task> GetAllAsync() } public async Task<(IEnumerable events, int pageNumber,int pageSize, int totalPages, int totalElements)> BrowseEventsAsync(int pageNumber, int pageSize, - string name, string organizer, DateTime dateFrom, DateTime dateTo, IEnumerable sortBy, - string direction, IEnumerable eventIds = null) + string name, string organizer, DateTime dateFrom, DateTime dateTo, Category? category, State? state, + IEnumerable sortBy, string direction, IEnumerable eventIds = null) { var filterDefinition = Extensions.ToFilterDefinition(name, dateFrom, dateTo, eventIds) .AddOrganizerNameFilter(organizer) - .AddStateFilter(State.Published); + .AddCategoryFilter(category) + .AddStateFilter(state); var sortDefinition = Extensions.ToSortDefinition(sortBy, direction); var pagedEvents = await BrowseAsync(filterDefinition, sortDefinition, pageNumber, pageSize); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index a29781cbc..22bc12639 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -107,6 +107,16 @@ public static FilterDefinition AddOrganizerIdFilter (this FilterD return filterDefinition; } + public static FilterDefinition AddCategoryFilter (this FilterDefinition filterDefinition, Category? category) + { + if (category != null) + { + filterDefinition &= FilterDefinitionBuilder.Eq(x => x.Category, category); + } + + return filterDefinition; + } + public static FilterDefinition AddStateFilter (this FilterDefinition filterDefinition, State? state) { if (state != null) @@ -117,6 +127,20 @@ public static FilterDefinition AddStateFilter (this FilterDefinit return filterDefinition; } + public static FilterDefinition AddRestrictedStateFilter (this FilterDefinition filterDefinition, State? state) + { + if (state != null) + { + filterDefinition &= FilterDefinitionBuilder.Eq(x => x.State, state); + } + else + { + filterDefinition &= FilterDefinitionBuilder.In(x => x.State, new[] { State.Published, State.Archived }); + } + + return filterDefinition; + } + public static SortDefinition ToSortDefinition(IEnumerable sortByArguments, string direction) { var sort = sortByArguments.ToList(); @@ -128,7 +152,8 @@ public static SortDefinition ToSortDefinition(IEnumerable var sortDefinition = sort .Select(sortBy => direction == "asc" ? sortDefinitionBuilder.Ascending(sortBy) - : sortDefinitionBuilder.Descending(sortBy)); + : sortDefinitionBuilder.Descending(sortBy)) + .Append(sortDefinitionBuilder.Ascending("State")); var sortCombined = sortDefinitionBuilder.Combine(sortDefinition); return sortCombined; diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs index 9e65c0c36..cf3e1e9ad 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Services/EventService.cs @@ -30,6 +30,8 @@ public async Task>> BrowseEventsAsync(Search { var dateFrom = DateTime.MinValue; var dateTo = DateTime.MinValue; + Category? category = null; + State? state = null; if(command.DateFrom != string.Empty) { dateFrom =_eventValidator.ParseDate(command.DateFrom, "DateFrom"); @@ -38,10 +40,19 @@ public async Task>> BrowseEventsAsync(Search { dateTo = _eventValidator.ParseDate(command.DateTo, "DateTo"); } + if(command.Category != string.Empty) + { + category = _eventValidator.ParseCategory(command.Category); + } + if(command.State != string.Empty) + { + state = _eventValidator.ParseState(command.State); + state = state != State.Published && state != State.Archived ? null : state; + } (int pageNumber, int pageSize) = _eventValidator.PageFilter(command.Pageable.Page, command.Pageable.Size); var result = await _eventRepository.BrowseEventsAsync( - pageNumber, pageSize, command.Name, command.Organizer, dateFrom, dateTo, + pageNumber, pageSize, command.Name, command.Organizer, dateFrom, dateTo, category, state, command.Pageable.Sort.SortBy, command.Pageable.Sort.Direction); var identity = _appContext.Identity; From b44cdce0cfa9d6869733c9a56ebe2a93f58b47f3 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 13:12:59 +0200 Subject: [PATCH 18/19] (#30) fix issue with sorting --- .../Mongo/Repositories/Extensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs index 22bc12639..0ca081222 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Repositories/Extensions.cs @@ -149,12 +149,12 @@ public static SortDefinition ToSortDefinition(IEnumerable sort.Add("StartDate"); } var sortDefinitionBuilder = Builders.Sort; + var sortStateDefinition = new[] { sortDefinitionBuilder.Descending("State") }; var sortDefinition = sort .Select(sortBy => direction == "asc" ? sortDefinitionBuilder.Ascending(sortBy) - : sortDefinitionBuilder.Descending(sortBy)) - .Append(sortDefinitionBuilder.Ascending("State")); - var sortCombined = sortDefinitionBuilder.Combine(sortDefinition); + : sortDefinitionBuilder.Descending(sortBy)); + var sortCombined = sortDefinitionBuilder.Combine(sortStateDefinition.Concat(sortDefinition)); return sortCombined; } From acfff6e712b8febab74088bb49e2d8b1bd78cdd2 Mon Sep 17 00:00:00 2001 From: eggwhat Date: Tue, 30 Apr 2024 13:23:35 +0200 Subject: [PATCH 19/19] (#30) add updatedAt field --- .../Commands/Handlers/AddEventHandler.cs | 2 +- .../Commands/Handlers/UpdateEventHandler.cs | 2 +- .../DTO/EventDto.cs | 1 + .../Entities/Event.cs | 17 +++++++++++------ .../Mongo/Documents/EventDocument.cs | 1 + .../Mongo/Documents/Extensions.cs | 4 +++- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs index e767250a2..8bc1b2a02 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/AddEventHandler.cs @@ -77,7 +77,7 @@ public async Task HandleAsync(AddEvent command, CancellationToken cancellationTo var organizer = new Organizer(command.OrganizerId, identity.Name, identity.Email, command.OrganizerId, string.Empty); var @event = Event.Create(command.EventId, command.Name, command.Description, startDate, endDate, - address, command.Capacity, command.Fee, category, state, publishDate, organizer); + address, command.Capacity, command.Fee, category, state, publishDate, organizer, now); await _eventRepository.AddAsync(@event); await _messageBroker.PublishAsync(new EventCreated(@event.Id, @event.Organizer.Id)); diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/UpdateEventHandler.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/UpdateEventHandler.cs index 19608dfde..de8ea2789 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/UpdateEventHandler.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/Commands/Handlers/UpdateEventHandler.cs @@ -69,7 +69,7 @@ public async Task HandleAsync(UpdateEvent command, CancellationToken cancellatio state = State.ToBePublished; } - @event.Update(name, description, startDate, endDate, address, capacity, fee, category, state, publishDate); + @event.Update(name, description, startDate, endDate, address, capacity, fee, category, state, publishDate, now); await _eventRepository.UpdateAsync(@event); await _messageBroker.PublishAsync(new EventUpdated(@event.Id, _dateTimeProvider.Now, identity.Id)); } diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs index e1e6202e4..fd4c8889a 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Application/DTO/EventDto.cs @@ -23,6 +23,7 @@ public class EventDto public string Category { get; set; } public string Status { get; set; } public DateTime PublishDate { get; set; } + public DateTime UpdatedAt { get; set; } public bool IsSignedUp { get; set; } public bool IsInterested { get; set; } public bool HasRated { get; set; } diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs index b303dd41e..f1686cedd 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Core/Entities/Event.cs @@ -23,6 +23,7 @@ public class Event: AggregateRoot public Category Category { get; private set; } public State State { get; private set; } public DateTime PublishDate { get; private set; } + public DateTime UpdatedAt { get; private set; } public IEnumerable InterestedStudents { @@ -44,7 +45,7 @@ public IEnumerable Ratings public Event(AggregateId id, string name, string description, DateTime startDate, DateTime endDate, Address location, int capacity, decimal fee, Category category, State state, DateTime publishDate, - Organizer organizer, IEnumerable interestedStudents = null, + Organizer organizer, DateTime updatedAt, IEnumerable interestedStudents = null, IEnumerable signedUpStudents = null, IEnumerable ratings = null) { Id = id; @@ -62,18 +63,20 @@ public Event(AggregateId id, string name, string description, DateTime startDat SignedUpStudents = signedUpStudents ?? Enumerable.Empty(); Ratings = ratings ?? Enumerable.Empty(); PublishDate = publishDate; + UpdatedAt = updatedAt; } public static Event Create(AggregateId id, string name, string description, DateTime startDate, DateTime endDate, - Address location, int capacity, decimal fee, Category category, State state, DateTime publishDate, Organizer organizer) + Address location, int capacity, decimal fee, Category category, State state, DateTime publishDate, + Organizer organizer, DateTime now) { var @event = new Event(id, name, description, startDate, endDate, location, capacity, fee, category, - state, publishDate, organizer); + state, publishDate, organizer, now); return @event; } - public void Update(string name, string description, DateTime startDate, DateTime endDate, - Address location, int capacity, decimal fee, Category category, State state, DateTime publishDate) + public void Update(string name, string description, DateTime startDate, DateTime endDate, Address location, + int capacity, decimal fee, Category category, State state, DateTime publishDate, DateTime now) { Name = name; Description = description; @@ -84,7 +87,8 @@ public void Update(string name, string description, DateTime startDate, DateTime Fee = fee; Category = category; State = state; - PublishDate = publishDate; + PublishDate = publishDate; + UpdatedAt = now; } public void SignUpStudent(Participant participant) @@ -167,6 +171,7 @@ public bool UpdateState(DateTime now) else return false; + UpdatedAt = now; return true; } diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs index 5859b603a..dffb5c2f7 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/EventDocument.cs @@ -23,6 +23,7 @@ public class EventDocument : IIdentifiable public Category Category { get; set; } public State State { get; set; } public DateTime PublishDate { get; set; } + public DateTime UpdatedAt { get; set; } public IEnumerable Ratings { get; set; } } } \ No newline at end of file diff --git a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs index ca2849c85..4c6f02558 100644 --- a/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs +++ b/MiniSpace.Services.Events/src/MiniSpace.Services.Events.Infrastructure/Mongo/Documents/Extensions.cs @@ -24,6 +24,7 @@ public static EventDto AsDto(this EventDocument document, Guid studentId) Category = document.Category.ToString(), Status = document.State.ToString(), PublishDate = document.PublishDate, + UpdatedAt = document.UpdatedAt, IsSignedUp = document.SignedUpStudents.Any(x => x.StudentId == studentId), IsInterested = document.InterestedStudents.Any(x => x.StudentId == studentId), HasRated = document.Ratings.Any(x => x.StudentId == studentId) @@ -32,7 +33,7 @@ public static EventDto AsDto(this EventDocument document, Guid studentId) public static Event AsEntity(this EventDocument document) => new (document.Id, document.Name, document.Description, document.StartDate, document.EndDate, document.Location, document.Capacity, document.Fee, document.Category, document.State, document.PublishDate, - document.Organizer, document.InterestedStudents, document.SignedUpStudents, document.Ratings); + document.Organizer, document.UpdatedAt,document.InterestedStudents, document.SignedUpStudents, document.Ratings); public static EventDocument AsDocument(this Event entity) => new () @@ -51,6 +52,7 @@ public static EventDocument AsDocument(this Event entity) Category = entity.Category, State = entity.State, PublishDate = entity.PublishDate, + UpdatedAt = entity.UpdatedAt, Ratings = entity.Ratings };