diff --git a/Api/Api.csproj b/Api/Api.csproj
index 7a53800..74b1ab7 100644
--- a/Api/Api.csproj
+++ b/Api/Api.csproj
@@ -8,14 +8,13 @@
..\docker-compose.dcproj
-
-
-
-
+
+
+
+
-
\ No newline at end of file
diff --git a/Api/Controllers/AuthController.cs b/Api/Controllers/AuthController.cs
index f181c34..c465d1b 100644
--- a/Api/Controllers/AuthController.cs
+++ b/Api/Controllers/AuthController.cs
@@ -1,11 +1,11 @@
using Api.Utilities;
using Application.Services;
-using Core.Dto.Request;
-using Core.Dto.Response;
using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Net;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Dto.Response;
namespace Api.Controllers
{
diff --git a/Api/Controllers/EtymologyController.cs b/Api/Controllers/EtymologyController.cs
index ce72345..e99ed18 100644
--- a/Api/Controllers/EtymologyController.cs
+++ b/Api/Controllers/EtymologyController.cs
@@ -1,5 +1,5 @@
-using Core.Repositories;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
+using YorubaOrganization.Core.Repositories;
namespace Api.Controllers
{
diff --git a/Api/Controllers/FeedbacksController.cs b/Api/Controllers/FeedbacksController.cs
index f69266b..1d22050 100644
--- a/Api/Controllers/FeedbacksController.cs
+++ b/Api/Controllers/FeedbacksController.cs
@@ -1,8 +1,6 @@
-using Api.Model.Request;
-using Application.Domain;
-using Application.Services;
+using Application.Services;
+using Core.Dto.Request;
using Core.Dto.Response;
-using Core.Entities.NameEntry.Collections;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
@@ -27,7 +25,7 @@ public FeedbacksController(NameEntryFeedbackService nameEntryFeedbackService, Na
[HttpGet]
[Route("{id}")]
- [ProducesResponseType(typeof(FeedbackDto), (int)HttpStatusCode.OK)]
+ [ProducesResponseType(typeof(NameFeedbackDto), (int)HttpStatusCode.OK)]
public async Task GetById(string id)
{
var feedback = await _nameEntryFeedbackService.GetFeedbackByIdAsync(id);
@@ -46,7 +44,7 @@ public async Task GetById(string id)
/// Optional name parameter
/// A list of all feedback (or just feedback for a given name)
[HttpGet]
- [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)]
+ [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)]
public async Task GetFeedback([FromQuery] string? name = null)
{
var feedbacks = string.IsNullOrWhiteSpace(name) ? await _nameEntryFeedbackService.FindAllAsync() :
@@ -64,7 +62,7 @@ public async Task GetFeedback([FromQuery] string? name = null)
[ProducesResponseType(typeof(Dictionary), (int)HttpStatusCode.Created)]
public async Task Create([FromBody] CreateNameFeedbackDto model)
{
- var nameEntry = await _nameEntryService.LoadName(model.Name);
+ var nameEntry = await _nameEntryService.LoadEntry(model.Name);
if (nameEntry == null)
{
@@ -91,7 +89,7 @@ public async Task Delete(string name, string feedbackId)
return BadRequest("Name parameter is required.");
}
- var nameEntry = await _nameEntryService.LoadName(name);
+ var nameEntry = await _nameEntryService.LoadEntry(name);
if (nameEntry == null)
{
@@ -122,7 +120,7 @@ public async Task DeleteAll([FromQuery][Required] string name)
return BadRequest("Name parameter is required.");
}
- var nameEntry = await _nameEntryService.LoadName(name);
+ var nameEntry = await _nameEntryService.LoadEntry(name);
if (nameEntry == null)
{
diff --git a/Api/Controllers/GeoLocationsController.cs b/Api/Controllers/GeoLocationsController.cs
index 8d4c5a9..ba0cfd8 100644
--- a/Api/Controllers/GeoLocationsController.cs
+++ b/Api/Controllers/GeoLocationsController.cs
@@ -1,11 +1,11 @@
using Api.Utilities;
using Application.Services;
-using Core.Dto.Request;
-using Core.Dto.Response;
-using Core.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Net;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Entities;
namespace Api.Controllers
{
diff --git a/Api/Controllers/NamesController.cs b/Api/Controllers/NamesController.cs
index 5ea13a7..ebfd54c 100644
--- a/Api/Controllers/NamesController.cs
+++ b/Api/Controllers/NamesController.cs
@@ -1,15 +1,15 @@
-using Api.Model.In;
-using Api.Utilities;
-using Application.Domain;
+using Api.Utilities;
using Application.Mappers;
+using Application.Services;
using Core.Dto.Request;
using Core.Dto.Response;
-using Core.Entities.NameEntry;
-using Core.Enums;
+using Core.Entities;
using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using MongoDB.Driver;
using System.Net;
+using YorubaOrganization.Core.Enums;
namespace Api.Controllers
{
@@ -63,13 +63,18 @@ public async Task Post([FromBody] CreateNameDto request)
///
///
[HttpGet("meta")]
- [ProducesResponseType(typeof(NamesMetadataDto[]), (int)HttpStatusCode.OK)]
+ [ProducesResponseType(typeof(NamesMetadataDto), (int)HttpStatusCode.OK)]
[AllowAnonymous]
public async Task GetMetaData()
{
var metaData = await _nameEntryService.GetMetadata();
-
- return Ok(metaData);
+ return Ok(new NamesMetadataDto
+ {
+ TotalNames = metaData.TotalEntries,
+ TotalPublishedNames = metaData.TotalPublishedEntries,
+ TotalModifiedNames = metaData.TotalModifiedEntries,
+ TotalNewNames = metaData.TotalNewEntries
+ });
}
///
@@ -96,7 +101,7 @@ public async Task GetAllNames(
IEnumerable names;
if (all.HasValue && all.Value)
{
- names = await _nameEntryService.GetAllNames(state, submittedBy);
+ names = await _nameEntryService.GetAllEntries(state, submittedBy);
return Ok(names.MapToDtoCollectionMini());
}
@@ -116,7 +121,7 @@ public async Task GetAllNames(
[AllowAnonymous]
public async Task GetName([FromRoute] string name)
{
- var nameEntry = await _nameEntryService.LoadName(name);
+ var nameEntry = await _nameEntryService.LoadEntry(name);
if (nameEntry == null)
{
@@ -146,14 +151,14 @@ public async Task UpdateName(string name, [FromBody] UpdateNameDt
return BadRequest(ModelState);
}
- var oldNameEntry = await _nameEntryService.LoadName(name);
+ var oldNameEntry = await _nameEntryService.LoadEntry(name);
if (oldNameEntry == null)
{
return NotFound($"{name} not in database");
}
- _ = await _nameEntryService.UpdateName(oldNameEntry, updated.MapToEntity());
+ _ = await _nameEntryService.Update(oldNameEntry, updated.MapToEntity());
return Ok(new { Message = "Name successfully updated" });
}
@@ -161,7 +166,7 @@ public async Task UpdateName(string name, [FromBody] UpdateNameDt
[Authorize(Policy = "AdminOnly")]
public async Task DeleteName(string name)
{
- var nameEntry = await _nameEntryService.LoadName(name);
+ var nameEntry = await _nameEntryService.LoadEntry(name);
if (nameEntry == null)
{
return NotFound($"{name} not found in the system so cannot be deleted");
@@ -177,7 +182,7 @@ public async Task DeleteName(string name)
public async Task DeleteNamesBatch(string[] names)
{
- var foundNames = (await _nameEntryService.LoadNames(names))?.Select(f => f.Name)?.ToArray();
+ var foundNames = (await _nameEntryService.LoadEntries(names))?.Select(f => f.Title)?.ToArray();
if (foundNames is null || foundNames.Length == 0)
{
@@ -186,7 +191,7 @@ public async Task DeleteNamesBatch(string[] names)
var notFoundNames = names.Where(d => !foundNames.Contains(d)).ToList();
- await _nameEntryService.DeleteNamesBatch(foundNames);
+ await _nameEntryService.DeleteEntriesBatch(foundNames);
string responseMessage = string.Join(", ", foundNames) + " deleted";
if (notFoundNames.Any())
diff --git a/Api/Controllers/SearchController.cs b/Api/Controllers/SearchController.cs
index 90714fa..c3b6ce2 100644
--- a/Api/Controllers/SearchController.cs
+++ b/Api/Controllers/SearchController.cs
@@ -1,16 +1,16 @@
using Api.Utilities;
-using Application.Domain;
using Application.Mappers;
using Application.Services;
-using Core.Cache;
using Core.Dto.Response;
-using Core.Entities.NameEntry;
-using Core.Enums;
-using Core.Events;
+using Core.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.Net;
+using YorubaOrganization.Core.Cache;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Enums;
+using YorubaOrganization.Core.Events;
namespace Api.Controllers
{
@@ -55,9 +55,9 @@ public async Task Search([FromQuery(Name = "q"), Required] string
var matches = await _searchService.Search(searchTerm);
// TODO: Check if the comparison here removes takes diacrits into consideration
- if (matches.Count() == 1 && matches.First().Name.Equals(searchTerm, StringComparison.CurrentCultureIgnoreCase))
+ if (matches.Count() == 1 && matches.First().Title.Equals(searchTerm, StringComparison.CurrentCultureIgnoreCase))
{
- await _eventPubService.PublishEvent(new ExactNameSearched(matches.First().Name));
+ await _eventPubService.PublishEvent(new ExactEntrySearched(matches.First().Title));
}
return Ok(matches.MapToDtoCollection());
@@ -92,11 +92,11 @@ public async Task SearchByStartsWith(string searchTerm)
[ProducesResponseType(typeof(NameEntryDto), (int)HttpStatusCode.OK)]
public async Task SearchOne(string searchTerm)
{
- NameEntryDto nameEntry = await _searchService.GetName(searchTerm);
+ var nameEntry = await _searchService.GetName(searchTerm);
if(nameEntry != null)
{
- await _eventPubService.PublishEvent(new ExactNameSearched(nameEntry.Name));
+ await _eventPubService.PublishEvent(new ExactEntrySearched(nameEntry.Name));
}
return Ok(nameEntry);
@@ -158,7 +158,7 @@ public async Task GetRecentStats()
[Authorize(Policy = "AdminAndProLexicographers")]
public async Task PublishName([FromRoute] string name)
{
- var nameEntry = await _nameEntryService.LoadName(name);
+ var nameEntry = await _nameEntryService.LoadEntry(name);
if (nameEntry == null)
{
return BadRequest(ResponseHelper.GetResponseDict($"{name} not found in the repository so not indexed"));
@@ -170,7 +170,7 @@ public async Task PublishName([FromRoute] string name)
return BadRequest(ResponseHelper.GetResponseDict($"{name} is already indexed"));
}
- await _nameEntryService.PublishName(nameEntry, User!.Identity!.Name!);
+ await _nameEntryService.PublishEntry(nameEntry, User!.Identity!.Name!);
return StatusCode((int)HttpStatusCode.Created, ResponseHelper.GetResponseDict($"{name} has been published"));
}
@@ -189,7 +189,7 @@ public async Task PublishNames([FromBody] string[] names)
// TODO Later: Optimize by fetching all names in one database call instead of one-by-one.
foreach (var name in names)
{
- var entry = await _nameEntryService.LoadName(name);
+ var entry = await _nameEntryService.LoadEntry(name);
if (entry != null && entry.State != State.PUBLISHED)
{
entriesToIndex.Add(entry);
@@ -204,10 +204,10 @@ public async Task PublishNames([FromBody] string[] names)
foreach (var nameEntry in entriesToIndex)
{
// TODO Later: The names should be updated in one batch instead of one-by-one.
- await _nameEntryService.PublishName(nameEntry, User!.Identity!.Name!);
+ await _nameEntryService.PublishEntry(nameEntry, User!.Identity!.Name!);
}
- var successMessage = $"The following names were successfully indexed: {string.Join(',', entriesToIndex.Select(x => x.Name))}";
+ var successMessage = $"The following names were successfully indexed: {string.Join(',', entriesToIndex.Select(x => x.Title))}";
return StatusCode((int)HttpStatusCode.Created, ResponseHelper.GetResponseDict(successMessage));
}
@@ -220,7 +220,7 @@ public async Task PublishNames([FromBody] string[] names)
[Authorize(Policy = "AdminAndProLexicographers")]
public async Task UnpublishName([FromRoute] string name)
{
- var entry = await _nameEntryService.FindByNameAndState(name, State.PUBLISHED);
+ var entry = await _nameEntryService.FindByTitleAndState(name, State.PUBLISHED);
if (entry == null)
{
@@ -228,7 +228,7 @@ public async Task UnpublishName([FromRoute] string name)
}
entry.State = State.NEW;
- await _nameEntryService.UpdateName(entry);
+ await _nameEntryService.Update(entry);
return Ok(ResponseHelper.GetResponseDict($"{name} removed from index."));
}
@@ -245,7 +245,7 @@ public async Task UnpublishNames([FromBody] string[] names)
foreach (var name in names)
{
- var entry = await _nameEntryService.FindByNameAndState(name, State.PUBLISHED);
+ var entry = await _nameEntryService.FindByTitleAndState(name, State.PUBLISHED);
if (entry == null)
{
@@ -254,8 +254,8 @@ public async Task UnpublishNames([FromBody] string[] names)
else
{
entry.State = State.UNPUBLISHED;
- await _nameEntryService.UpdateName(entry);
- unpublishedNames.Add(entry.Name);
+ await _nameEntryService.Update(entry);
+ unpublishedNames.Add(entry.Title);
}
}
diff --git a/Api/Controllers/SuggestedNameController.cs b/Api/Controllers/SuggestedNameController.cs
index ffb56af..c4bf24e 100644
--- a/Api/Controllers/SuggestedNameController.cs
+++ b/Api/Controllers/SuggestedNameController.cs
@@ -6,7 +6,6 @@
using Microsoft.AspNetCore.Mvc;
using System.Net;
using Application.Mappers;
-using Application.Validation;
using FluentValidation;
namespace Api.Controllers;
diff --git a/Api/ExceptionHandler/GlobalExceptionHandling.cs b/Api/ExceptionHandler/GlobalExceptionHandling.cs
index 3f18d1c..f73cc7b 100644
--- a/Api/ExceptionHandler/GlobalExceptionHandling.cs
+++ b/Api/ExceptionHandler/GlobalExceptionHandling.cs
@@ -1,9 +1,9 @@
namespace Api.ExceptionHandler
{
using Api.Utilities;
- using Application.Exceptions;
using System.Net;
using System.Text.Json;
+ using YorubaOrganization.Application.Exceptions;
public class GlobalExceptionHandlingMiddleware
{
diff --git a/Api/Program.cs b/Api/Program.cs
index d8f4f4b..da675e0 100644
--- a/Api/Program.cs
+++ b/Api/Program.cs
@@ -1,16 +1,10 @@
using Api.ExceptionHandler;
-using Application.Domain;
-using Application.Events;
using Application.Migrator;
using Application.Services;
using Application.Validation;
-using Core.Cache;
-using Core.Enums;
-using Core.Events;
using Core.StringObjectConverters;
using FluentValidation;
using Infrastructure.Twitter;
-using Infrastructure.MongoDB;
using Microsoft.AspNetCore.Authentication;
using Microsoft.OpenApi.Models;
using MySqlConnector;
@@ -19,6 +13,11 @@
using Infrastructure.Hangfire;
using Infrastructure.Redis;
using Ardalis.GuardClauses;
+using YorubaOrganization.Core.Enums;
+using YorubaOrganization.Core.Events;
+using YorubaOrganization.Core.Cache;
+using Application.EventHandlers;
+using Infrastructure.MongoDB;
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
@@ -119,7 +118,11 @@
//Validation
services.AddValidatorsFromAssemblyContaining();
-services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(ExactNameSearchedAdapter).Assembly));
+services.AddMediatR(cfg =>
+{
+ cfg.RegisterServicesFromAssembly(typeof(PostPublishedNameCommandHandler).Assembly);
+ cfg.RegisterServicesFromAssembly(typeof(ExactEntrySearchedEventHandler).Assembly);
+});
// Twitter integration configuration
services.AddSingleton();
diff --git a/Api/Utilities/CustomSchemaFilter.cs b/Api/Utilities/CustomSchemaFilter.cs
index 84153ed..863f8ae 100644
--- a/Api/Utilities/CustomSchemaFilter.cs
+++ b/Api/Utilities/CustomSchemaFilter.cs
@@ -1,6 +1,6 @@
-using Core.Dto;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
+using YorubaOrganization.Core.Dto;
public class CustomSchemaFilter : ISchemaFilter
{
diff --git a/Application/Application.csproj b/Application/Application.csproj
index 1310f6a..e4d82e4 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -10,12 +10,13 @@
+
-
+
diff --git a/Application/Cache/ICacheService.cs b/Application/Cache/ICacheService.cs
index 8cc97c4..2c38165 100644
--- a/Application/Cache/ICacheService.cs
+++ b/Application/Cache/ICacheService.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Cache
+namespace Application.Cache
{
public interface ICacheService
{
diff --git a/Application/EventHandlers/DeletedNameCachingHandler.cs b/Application/EventHandlers/DeletedNameCachingHandler.cs
deleted file mode 100644
index 79df525..0000000
--- a/Application/EventHandlers/DeletedNameCachingHandler.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using Application.Events;
-using Core.Cache;
-using MediatR;
-using Microsoft.Extensions.Logging;
-
-namespace Application.EventHandlers
-{
- public class DeletedNameCachingHandler : INotificationHandler
- {
- private readonly IRecentIndexesCache _recentIndexesCache;
- private readonly IRecentSearchesCache _recentSearchesCache;
- private readonly ILogger _logger;
-
- public DeletedNameCachingHandler(
- IRecentIndexesCache recentIndexesCache,
- IRecentSearchesCache recentSearchesCache,
- ILogger logger
- )
- {
- _recentIndexesCache = recentIndexesCache;
- _recentSearchesCache = recentSearchesCache;
- _logger = logger;
- }
-
- public async Task Handle(NameDeletedAdapter notification, CancellationToken cancellationToken)
- {
- try
- {
- await _recentIndexesCache.Remove(notification.Name);
- await _recentSearchesCache.Remove(notification.Name);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error occurred while removing deleted name '{name}' from cache.", notification.Name);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Application/EventHandlers/NameIndexedEventHandler.cs b/Application/EventHandlers/EntryIndexedEventHandler.cs
similarity index 81%
rename from Application/EventHandlers/NameIndexedEventHandler.cs
rename to Application/EventHandlers/EntryIndexedEventHandler.cs
index dc09fc1..fbf9ace 100644
--- a/Application/EventHandlers/NameIndexedEventHandler.cs
+++ b/Application/EventHandlers/EntryIndexedEventHandler.cs
@@ -1,10 +1,11 @@
using Application.Events;
-using Core.Cache;
+using Core.Events;
using MediatR;
+using YorubaOrganization.Core.Cache;
namespace Application.EventHandlers
{
- public class NameIndexedEventHandler : INotificationHandler
+ public class NameIndexedEventHandler : INotificationHandler
{
public IRecentIndexesCache _recentIndexesCache;
private readonly IMediator _mediator;
@@ -17,7 +18,7 @@ public NameIndexedEventHandler(
_mediator = mediator;
}
- public async Task Handle(NameIndexedAdapter notification, CancellationToken cancellationToken)
+ public async Task Handle(NameIndexed notification, CancellationToken cancellationToken)
{
await _recentIndexesCache.Stack(notification.Name);
await _mediator.Publish(new PostPublishedNameCommand(notification.Name, notification.Meaning), cancellationToken);
diff --git a/Application/EventHandlers/ExactNameSearchedEventHandler.cs b/Application/EventHandlers/ExactNameSearchedEventHandler.cs
deleted file mode 100644
index a7685b1..0000000
--- a/Application/EventHandlers/ExactNameSearchedEventHandler.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Application.Events;
-using Core.Cache;
-using MediatR;
-
-namespace Application.EventHandlers
-{
- public class ExactNameSearchedEventHandler : INotificationHandler
- {
- public IRecentSearchesCache _recentSearchesCache;
-
- public ExactNameSearchedEventHandler(IRecentSearchesCache recentSearchesCache)
- {
- _recentSearchesCache = recentSearchesCache;
- }
-
- public async Task Handle(ExactNameSearchedAdapter notification, CancellationToken cancellationToken)
- {
- await _recentSearchesCache.Stack(notification.SearchTerm);
- }
- }
-}
diff --git a/Application/Events/ExactNameSearchedAdapter.cs b/Application/Events/ExactNameSearchedAdapter.cs
deleted file mode 100644
index 21df021..0000000
--- a/Application/Events/ExactNameSearchedAdapter.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Core.Events;
-using MediatR;
-
-namespace Application.Events
-{
- public record ExactNameSearchedAdapter : ExactNameSearched, INotification
- {
- public ExactNameSearchedAdapter(ExactNameSearched theEvent) : base(theEvent.SearchTerm)
- {
- }
- }
-}
\ No newline at end of file
diff --git a/Application/Events/NameDeletedAdapter.cs b/Application/Events/NameDeletedAdapter.cs
deleted file mode 100644
index a91e513..0000000
--- a/Application/Events/NameDeletedAdapter.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Core.Events;
-using MediatR;
-
-namespace Application.Events;
-
-public record NameDeletedAdapter : NameDeleted, INotification
-{
- public NameDeletedAdapter(NameDeleted theEvent) : base(theEvent.Name)
- {
- }
-}
\ No newline at end of file
diff --git a/Application/Events/NameEntryNameUpdatedAdapter.cs b/Application/Events/NameEntryNameUpdatedAdapter.cs
deleted file mode 100644
index 74821fd..0000000
--- a/Application/Events/NameEntryNameUpdatedAdapter.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Core.Events;
-using MediatR;
-
-namespace Application.Events;
-
-public record NameEntryNameUpdatedAdapter : NameEntryNameUpdated, INotification
-{
- public NameEntryNameUpdatedAdapter(NameEntryNameUpdated theEvent) : base(theEvent.OriginalName, theEvent.NewName)
- {
- }
-}
\ No newline at end of file
diff --git a/Application/Events/NameIndexedAdapter.cs b/Application/Events/NameIndexedAdapter.cs
deleted file mode 100644
index 10c9f84..0000000
--- a/Application/Events/NameIndexedAdapter.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Core.Events;
-using MediatR;
-
-namespace Application.Events;
-
-public record NameIndexedAdapter : NameIndexed, INotification
-{
- public NameIndexedAdapter(NameIndexed theEvent) : base(theEvent.Name, theEvent.Meaning)
- {
- }
-}
\ No newline at end of file
diff --git a/Application/Events/NonExistingNameUpdateAttemptedAdapter.cs b/Application/Events/NonExistingNameUpdateAttemptedAdapter.cs
deleted file mode 100644
index 1d043d9..0000000
--- a/Application/Events/NonExistingNameUpdateAttemptedAdapter.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Core.Events;
-using MediatR;
-
-namespace Application.Events
-{
- public record NonExistingNameUpdateAttemptedAdapter : NonExistingNameUpdateAttempted, INotification
- {
- public NonExistingNameUpdateAttemptedAdapter(string name) : base(name) { }
-
- public NonExistingNameUpdateAttemptedAdapter(NonExistingNameUpdateAttempted theEvent) : base(theEvent.Name)
- {
- }
- }
-}
\ No newline at end of file
diff --git a/Application/Exceptions/ClientException.cs b/Application/Exceptions/ClientException.cs
deleted file mode 100644
index 6b08495..0000000
--- a/Application/Exceptions/ClientException.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Application.Exceptions
-{
- ///
- /// TODO: This should be a 400 Bad Request exception
- ///
- public class ClientException : Exception
- {
- public ClientException()
- {
- }
-
- public ClientException(string message)
- : base(message)
- {
- }
-
- public ClientException(string message, Exception inner)
- : base(message, inner)
- {
- }
- }
-
-}
diff --git a/Application/Exceptions/DuplicateException.cs b/Application/Exceptions/DuplicateException.cs
deleted file mode 100644
index 976451d..0000000
--- a/Application/Exceptions/DuplicateException.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Application.Exceptions
-{
- public class DuplicateException : ClientException
- {
- public DuplicateException() : base() { }
-
- public DuplicateException(string message) : base(message) { }
- }
-}
diff --git a/Application/Exceptions/RepositoryAccessException.cs b/Application/Exceptions/RepositoryAccessException.cs
deleted file mode 100644
index 64abb84..0000000
--- a/Application/Exceptions/RepositoryAccessException.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Application.Exceptions
-{
- ///
- /// TODO: This should be a 400 Bad Request exception
- ///
- public class RepositoryAccessException : Exception
- {
- public RepositoryAccessException()
- {
- }
-
- public RepositoryAccessException(string message)
- : base(message)
- {
- }
-
- public RepositoryAccessException(string message, Exception inner)
- : base(message, inner)
- {
- }
- }
-
-}
diff --git a/Application/Exceptions/UnpublishedNameUpdateException.cs b/Application/Exceptions/UnpublishedNameUpdateException.cs
deleted file mode 100644
index bcf5def..0000000
--- a/Application/Exceptions/UnpublishedNameUpdateException.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Application.Exceptions
-{
- public class UnpublishedNameUpdateException : ClientException
- {
- public UnpublishedNameUpdateException() : base("There is an unpublished update on this name already") { }
- }
-}
diff --git a/Application/Mappers/NameEntryMapper.cs b/Application/Mappers/NameEntryMapper.cs
index 57f9200..990b7f8 100644
--- a/Application/Mappers/NameEntryMapper.cs
+++ b/Application/Mappers/NameEntryMapper.cs
@@ -1,10 +1,12 @@
-using Core.Dto;
-using Core.Dto.Request;
+using Core.Dto.Request;
using Core.Dto.Response;
using Core.Entities;
-using Core.Entities.NameEntry;
-using Core.Entities.NameEntry.Collections;
-using Core.Enums;
+using YorubaOrganization.Core.Dto;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Entities;
+using YorubaOrganization.Core.Entities.Partials;
+using YorubaOrganization.Core.Enums;
namespace Application.Mappers
{
@@ -19,7 +21,7 @@ public static NameEntryMiniDto[] MapToDtoCollectionMini(this IEnumerable new NameEntryMiniDto
{
- Name = nameEntry.Name,
+ Name = nameEntry.Title,
Meaning = nameEntry.Meaning,
SubmittedBy = nameEntry.CreatedBy
}).ToArray();
@@ -29,12 +31,12 @@ public static NameEntry MapToEntity(this NameDto request)
{
return new NameEntry
{
- Name = request.Name.Trim(),
+ Title = request.Name.Trim(),
Pronunciation = request.Pronunciation?.Trim(),
Meaning = request.Meaning.Trim(),
ExtendedMeaning = request.ExtendedMeaning?.Trim(),
Morphology = request.Morphology ?? new List(),
- Media = request.Media ?? new List(),
+ MediaLinks = request.MediaLinks,
State = request.State ?? State.NEW,
Etymology = request.Etymology.Select(et => new Etymology(et.Part, et.Meaning)).ToList(),
Videos = request.Videos.Select(ev => new EmbeddedVideo(ev.VideoId, ev.Caption)).ToList(),
@@ -42,7 +44,7 @@ public static NameEntry MapToEntity(this NameDto request)
GeoLocation = request.GeoLocation.Select(ge => new GeoLocation(ge.Place, ge.Region)).ToList(),
FamousPeople = request.FamousPeople ?? new List(),
Syllables = request.Syllables ?? new List(),
- Variants = request.Variants ?? new List(),
+ VariantsV2 = request.VariantsV2,
CreatedBy = request.SubmittedBy,
UpdatedBy = request.SubmittedBy
};
@@ -54,21 +56,21 @@ public static NameEntryDto MapToDto(this NameEntry nameEntry)
{
Pronunciation = nameEntry.Pronunciation,
IpaNotation = nameEntry.IpaNotation,
- Variants = (CommaSeparatedString)nameEntry.Variants,
+ Variants = (CommaSeparatedString)nameEntry.VariantsV2.Select(v => v.Title).ToList(),
Syllables = (HyphenSeparatedString)nameEntry.Syllables,
Meaning = nameEntry.Meaning,
ExtendedMeaning = nameEntry.ExtendedMeaning,
Morphology = (CommaSeparatedString)nameEntry.Morphology,
GeoLocation = nameEntry.GeoLocation.Select(ge => new GeoLocationDto(ge.Id, ge.Place, ge.Region)).ToList(),
FamousPeople = (CommaSeparatedString)nameEntry.FamousPeople,
- Media = (CommaSeparatedString)nameEntry.Media,
+ Media = (CommaSeparatedString)nameEntry.MediaLinks.Select(m => m.Url).ToList(),
SubmittedBy = nameEntry.CreatedBy,
Etymology = nameEntry.Etymology.Select(et => new EtymologyDto(et.Part, et.Meaning)).ToList(),
Videos = nameEntry.Videos.Select(v => new EmbeddedVideoDto(v.VideoId, v.Caption)).ToList(),
State = nameEntry.State,
CreatedAt = nameEntry.CreatedAt,
UpdatedAt = nameEntry.UpdatedAt,
- Name = nameEntry.Name
+ Name = nameEntry.Title
};
}
}
diff --git a/Application/Mappers/SuggestedNameMapper.cs b/Application/Mappers/SuggestedNameMapper.cs
index b26dc52..40f6482 100644
--- a/Application/Mappers/SuggestedNameMapper.cs
+++ b/Application/Mappers/SuggestedNameMapper.cs
@@ -2,6 +2,8 @@
using Core.Dto.Response;
using Core.Entities;
using MongoDB.Bson;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Entities;
namespace Application.Mappers;
diff --git a/Application/Migrator/MigrationDTOs.cs/etymology.cs b/Application/Migrator/MigrationDTOs.cs/etymology.cs
index 99119ed..0177c2b 100644
--- a/Application/Migrator/MigrationDTOs.cs/etymology.cs
+++ b/Application/Migrator/MigrationDTOs.cs/etymology.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Migrator.MigrationDTOs.cs
+namespace Application.Migrator.MigrationDTOs.cs
{
internal class etymology
{
diff --git a/Application/Migrator/MigrationDTOs.cs/geolocation.cs b/Application/Migrator/MigrationDTOs.cs/geolocation.cs
index 6ac1bee..241c428 100644
--- a/Application/Migrator/MigrationDTOs.cs/geolocation.cs
+++ b/Application/Migrator/MigrationDTOs.cs/geolocation.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Migrator.MigrationDTOs.cs
+namespace Application.Migrator.MigrationDTOs.cs
{
internal class geolocation
{
diff --git a/Application/Migrator/MigrationDTOs.cs/nameentry.cs b/Application/Migrator/MigrationDTOs.cs/nameentry.cs
index ead2cc8..0a430e8 100644
--- a/Application/Migrator/MigrationDTOs.cs/nameentry.cs
+++ b/Application/Migrator/MigrationDTOs.cs/nameentry.cs
@@ -1,10 +1,5 @@
-using Core.Entities;
-using Core.Entities.NameEntry.Collections;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using YorubaOrganization.Core.Entities;
+using YorubaOrganization.Core.Entities.Partials;
namespace Application.Migrator.MigrationDTOs.cs
{
diff --git a/Application/Migrator/MigrationDTOs.cs/nameentryfeedback.cs b/Application/Migrator/MigrationDTOs.cs/nameentryfeedback.cs
index a3f304e..44439a7 100644
--- a/Application/Migrator/MigrationDTOs.cs/nameentryfeedback.cs
+++ b/Application/Migrator/MigrationDTOs.cs/nameentryfeedback.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Migrator.MigrationDTOs.cs
+namespace Application.Migrator.MigrationDTOs.cs
{
internal class nameentryfeedback
{
diff --git a/Application/Migrator/MigrationDTOs.cs/nameentryvideos.cs b/Application/Migrator/MigrationDTOs.cs/nameentryvideos.cs
index 60c734d..849121a 100644
--- a/Application/Migrator/MigrationDTOs.cs/nameentryvideos.cs
+++ b/Application/Migrator/MigrationDTOs.cs/nameentryvideos.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Migrator.MigrationDTOs.cs
+namespace Application.Migrator.MigrationDTOs.cs
{
internal class nameentryvideos
{
diff --git a/Application/Migrator/MigrationDTOs.cs/suggested_name.cs b/Application/Migrator/MigrationDTOs.cs/suggested_name.cs
index d709667..84d6546 100644
--- a/Application/Migrator/MigrationDTOs.cs/suggested_name.cs
+++ b/Application/Migrator/MigrationDTOs.cs/suggested_name.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Migrator.MigrationDTOs.cs
+namespace Application.Migrator.MigrationDTOs.cs
{
internal class suggested_name
{
diff --git a/Application/Migrator/MigrationDTOs.cs/users.cs b/Application/Migrator/MigrationDTOs.cs/users.cs
index 6d9e5d0..a30c561 100644
--- a/Application/Migrator/MigrationDTOs.cs/users.cs
+++ b/Application/Migrator/MigrationDTOs.cs/users.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Application.Migrator.MigrationDTOs.cs
+namespace Application.Migrator.MigrationDTOs.cs
{
internal class users
{
diff --git a/Application/Migrator/SQLToMongoMigrator.cs b/Application/Migrator/SQLToMongoMigrator.cs
index 7efbcf5..ca19c82 100644
--- a/Application/Migrator/SQLToMongoMigrator.cs
+++ b/Application/Migrator/SQLToMongoMigrator.cs
@@ -1,14 +1,15 @@
using Application.Migrator.MigrationDTOs.cs;
-using Core.Dto;
+using Core.Dto.Request;
using Core.Entities;
-using Core.Entities.NameEntry;
-using Core.Entities.NameEntry.Collections;
-using Core.Enums;
using Dapper;
using Microsoft.Extensions.Configuration;
using MongoDB.Bson;
using MongoDB.Driver;
using MySqlConnector;
+using YorubaOrganization.Core.Dto;
+using YorubaOrganization.Core.Entities;
+using YorubaOrganization.Core.Entities.Partials;
+using YorubaOrganization.Core.Enums;
namespace Application.Migrator
{
@@ -97,26 +98,34 @@ on a.place equals b.geo_location_place
Select(s => new EmbeddedVideo(s.url, s.caption)).ToList();
}
- List documentsToInsert = name_entry.Select(s => new NameEntry()
- {
- Id = ObjectId.GenerateNewId().ToString(),
- Name = s.name,
- ExtendedMeaning = s.extended_meaning,
- FamousPeople = new CommaSeparatedString(s.famous_people),
- IpaNotation = s.ipa_notation,
- Meaning = s.meaning,
- Media = new CommaSeparatedString(s.media),
- Morphology = new CommaSeparatedString(s.morphology),
- Pronunciation = s.pronunciation,
- CreatedBy = s.submitted_by,
- Syllables = new HyphenSeparatedString(s.syllables),
- Variants = new CommaSeparatedString(s.variants),
- State = GetPublishState(s.state),
- Etymology = s.etymology,
- GeoLocation = s.geoLocations,
- Feedbacks = s.feedbacks,
- Videos = s.embeddedVideo
- }).ToList();
+ List documentsToInsert = name_entry.Select(s => {
+ var updateNameDto = new UpdateNameDto
+ {
+ Media = new CommaSeparatedString(s.media),
+ Variants = new CommaSeparatedString(s.variants)
+ };
+
+ return new NameEntry()
+ {
+ Id = ObjectId.GenerateNewId().ToString(),
+ Title = s.name,
+ ExtendedMeaning = s.extended_meaning,
+ FamousPeople = new CommaSeparatedString(s.famous_people),
+ IpaNotation = s.ipa_notation,
+ Meaning = s.meaning,
+ MediaLinks = updateNameDto.MediaLinks,
+ Morphology = new CommaSeparatedString(s.morphology),
+ Pronunciation = s.pronunciation,
+ CreatedBy = s.submitted_by,
+ Syllables = new HyphenSeparatedString(s.syllables),
+ VariantsV2 = updateNameDto.VariantsV2,
+ State = GetPublishState(s.state),
+ Etymology = s.etymology,
+ GeoLocation = s.geoLocations,
+ Feedbacks = s.feedbacks,
+ Videos = s.embeddedVideo
+ };
+ }).ToList();
_nameEntryCollection.DeleteMany(FilterDefinition.Empty);
_nameEntryCollection.InsertMany(documentsToInsert);
diff --git a/Application/Services/BasicAuthHandler.cs b/Application/Services/BasicAuthHandler.cs
index f54c1fc..42b785a 100644
--- a/Application/Services/BasicAuthHandler.cs
+++ b/Application/Services/BasicAuthHandler.cs
@@ -1,6 +1,4 @@
-using Core.Entities;
-using Core.Repositories;
-using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Data;
@@ -8,6 +6,8 @@
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
+using YorubaOrganization.Core.Entities;
+using YorubaOrganization.Core.Repositories;
namespace Application.Services
{
diff --git a/Application/Services/EventPubService.cs b/Application/Services/EventPubService.cs
index f97828c..dc2a153 100644
--- a/Application/Services/EventPubService.cs
+++ b/Application/Services/EventPubService.cs
@@ -1,6 +1,6 @@
-using Core.Events;
+using Ardalis.GuardClauses;
using MediatR;
-using System.Reflection;
+using YorubaOrganization.Core.Events;
namespace Application.Services
{
@@ -15,16 +15,8 @@ public EventPubService(IMediator mediator)
public async Task PublishEvent(T theEvent)
{
- var adapterClassName = typeof(T).Name + "Adapter";
- Type? adapterType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.Name == adapterClassName);
-
- if (adapterType == null)
- {
- throw new InvalidOperationException("Adapter type not found for " + typeof(T).FullName);
- }
-
- var adapterEvent = Activator.CreateInstance(adapterType, theEvent)!;
- await _mediator.Publish(adapterEvent);
+ Guard.Against.Null(theEvent, nameof(theEvent));
+ await _mediator.Publish(theEvent);
}
}
}
diff --git a/Application/Services/GeoLocationsService.cs b/Application/Services/GeoLocationsService.cs
index e09a01f..488d039 100644
--- a/Application/Services/GeoLocationsService.cs
+++ b/Application/Services/GeoLocationsService.cs
@@ -1,6 +1,6 @@
-using Application.Exceptions;
-using Core.Entities;
-using Core.Repositories;
+using YorubaOrganization.Application.Exceptions;
+using YorubaOrganization.Core.Entities;
+using YorubaOrganization.Core.Repositories;
namespace Application.Services
{
diff --git a/Application/Services/NameEntryFeedbackService.cs b/Application/Services/NameEntryFeedbackService.cs
index 2f5625f..c55d8f3 100644
--- a/Application/Services/NameEntryFeedbackService.cs
+++ b/Application/Services/NameEntryFeedbackService.cs
@@ -12,12 +12,12 @@ public NameEntryFeedbackService(INameEntryFeedbackRepository nameEntryFeedbackRe
_nameEntryFeedbackRepository = nameEntryFeedbackRepository;
}
- public async Task> FindAllAsync()
+ public async Task> FindAllAsync()
{
return await _nameEntryFeedbackRepository.FindAllAsync();
}
- public async Task> FindByNameAsync(string name)
+ public async Task> FindByNameAsync(string name)
{
return await _nameEntryFeedbackRepository.FindByNameAsync(name);
}
@@ -32,7 +32,7 @@ public async Task DeleteAllFeedbackForNameAsync(string name)
await _nameEntryFeedbackRepository.DeleteAllFeedbackForNameAsync(name);
}
- public async Task GetFeedbackByIdAsync(string feedbackId)
+ public async Task GetFeedbackByIdAsync(string feedbackId)
{
return await _nameEntryFeedbackRepository.GetFeedbackByIdAsync(feedbackId);
}
diff --git a/Application/Services/NameEntryService.cs b/Application/Services/NameEntryService.cs
index a014b2f..79cd358 100644
--- a/Application/Services/NameEntryService.cs
+++ b/Application/Services/NameEntryService.cs
@@ -1,14 +1,13 @@
-using Application.Exceptions;
-using Core.Dto.Response;
-using Core.Entities.NameEntry;
-using Core.Enums;
+using Core.Entities;
using Core.Events;
using Core.Repositories;
using Microsoft.Extensions.Logging;
+using YorubaOrganization.Application.Services;
+using YorubaOrganization.Core.Events;
-namespace Application.Domain
+namespace Application.Services
{
- public class NameEntryService
+ public class NameEntryService : DictionaryEntryService
{
private readonly INameEntryRepository _nameEntryRepository;
private readonly IEventPubService _eventPubService;
@@ -18,128 +17,13 @@ public NameEntryService(
INameEntryRepository nameEntryRepository,
IEventPubService eventPubService,
ILogger logger
- )
+ ) : base(nameEntryRepository, eventPubService, logger)
{
_nameEntryRepository = nameEntryRepository;
_eventPubService = eventPubService;
_logger = logger;
}
- public async Task Create(NameEntry entry)
- {
- var name = entry.Name;
-
- var existingName = await _nameEntryRepository.FindByName(name);
- if (existingName != null)
- {
- existingName.Duplicates.Add(entry);
- await UpdateName(existingName);
- _logger.LogWarning("Someone attempted to create a new name over existing name: {name}.", name);
- return;
- }
-
- await CreateOrUpdateName(entry);
- }
-
- public async Task BulkCreate(List entries)
- {
- foreach (var entry in entries)
- {
- await Create(entry);
- // TODO Later: Ensure that removing batched writes to database here will not cause problems
- }
- }
-
- public async Task CreateOrUpdateName(NameEntry entry)
- {
- var updated = await UpdateNameWithUnpublish(entry);
-
- if (updated == null)
- {
- await _nameEntryRepository.Create(entry);
- }
-
- return updated ?? entry;
- }
-
- public async Task> SaveNames(List entries)
- {
- var savedNames = new List();
- foreach (var entry in entries)
- {
- savedNames.Add(await CreateOrUpdateName(entry));
- // TODO Later: Ensure that removing batched writes to database here will not cause problems
- }
- return savedNames;
- }
-
- public async Task UpdateName(NameEntry nameEntry)
- {
- return await _nameEntryRepository.Update(nameEntry.Name, nameEntry);
- }
-
- public async Task PublishName(NameEntry nameEntry, string username)
- {
- if (string.IsNullOrEmpty(username))
- {
- throw new ClientException("Unexpected. User must be logged in to publish a name!");
- }
-
- NameEntry? updates = nameEntry.Modified;
- string originalName = nameEntry.Name;
-
- if (updates != null)
- {
- // Copy latest updates to the main object as part of the publish operation.
- nameEntry.Name = updates.Name;
- nameEntry.Pronunciation = updates.Pronunciation;
- nameEntry.IpaNotation = updates.IpaNotation;
- nameEntry.Meaning = updates.Meaning;
- nameEntry.ExtendedMeaning = updates.ExtendedMeaning;
- nameEntry.Morphology = updates.Morphology;
- nameEntry.Media = updates.Media;
- nameEntry.State = updates.State;
- nameEntry.Etymology = updates.Etymology;
- nameEntry.Videos = updates.Videos;
- nameEntry.GeoLocation = updates.GeoLocation;
- nameEntry.FamousPeople = updates.FamousPeople;
- nameEntry.Syllables = updates.Syllables;
- nameEntry.Variants = updates.Variants;
- nameEntry.UpdatedBy = username;
-
- nameEntry.Modified = null;
- }
-
- nameEntry.State = State.PUBLISHED;
- await _nameEntryRepository.Update(originalName, nameEntry);
-
- // TODO Later: Use the outbox pattern to enforce event publishing after the DB update (https://www.youtube.com/watch?v=032SfEBFIJs&t=913s).
- await _eventPubService.PublishEvent(new NameIndexed(nameEntry.Name, nameEntry.Meaning));
- }
-
- public async Task UpdateNameWithUnpublish(NameEntry nameEntry)
- {
- if (nameEntry.State == State.PUBLISHED)
- {
- // Unpublish name if it is currently published since it is awaiting some changes.
- nameEntry.State = State.MODIFIED;
- }
-
- return await UpdateName(nameEntry);
- }
-
- ///
- /// Update an existing NameEntry with a new version.
- ///
- ///
- ///
- ///
- public async Task UpdateName(NameEntry originalEntry, NameEntry newEntry)
- {
- originalEntry.Modified = newEntry;
- return await UpdateNameWithUnpublish(originalEntry);
- }
-
public async Task> BulkUpdateNames(List nameEntries)
{
var updatedNames = new List();
@@ -147,7 +31,7 @@ public async Task> BulkUpdateNames(List nameEntries)
// TODO Later: Update all names in one batch
foreach (var nameEntry in nameEntries)
{
- var updated = await UpdateNameWithUnpublish(nameEntry);
+ var updated = await UpdateEntryWithUnpublish(nameEntry);
if (updated != null)
{
@@ -155,65 +39,17 @@ public async Task> BulkUpdateNames(List nameEntries)
}
else
{
- await _eventPubService.PublishEvent(new NonExistingNameUpdateAttempted(nameEntry.Name));
+ await _eventPubService.PublishEvent(new NonExistingEntryUpdateAttempted(nameEntry.Title));
}
}
return updatedNames;
}
- public async Task> ListNames()
+ public async override Task PublishEntry(NameEntry nameEntry, string username)
{
- var result = await _nameEntryRepository.ListAll();
- return result.ToList();
- }
-
- public async Task GetMetadata()
- {
- return await _nameEntryRepository.GetMetadata();
- }
-
- public async Task> FindBy(State state)
- {
- return await _nameEntryRepository.FindByState(state);
- }
-
- public async Task> GetAllNames(State? state, string? submittedBy)
- {
- return await _nameEntryRepository.GetAllNames(state, submittedBy);
- }
-
- public async Task> List(State? state, string? submittedBy, int pageNumber, int pageSize)
- {
- return await _nameEntryRepository.List(pageNumber, pageSize, state, submittedBy);
- }
-
- public async Task LoadName(string name)
- {
- return await _nameEntryRepository.FindByName(name);
- }
-
- public async Task> LoadNames(string[] names)
- {
- return await _nameEntryRepository.FindByNames(names);
- }
-
- public async Task Delete(string name)
- {
- await _nameEntryRepository.Delete(name);
- await PublishNameDeletedEvent(name);
- }
-
- private async Task PublishNameDeletedEvent(string name)
- {
- await _eventPubService.PublishEvent(new NameDeleted(name));
- }
-
- public async Task FindByNameAndState(string name, State state) =>
- await _nameEntryRepository.FindByNameAndState(name, state);
-
- public async Task DeleteNamesBatch(string[] names)
- {
- await _nameEntryRepository.DeleteMany(names);
+ await base.PublishEntry(nameEntry, username, n => n.Meaning, n => n.ExtendedMeaning, n => n.FamousPeople);
+ // TODO Later: Use the outbox pattern to enforce event publishing after the DB update (https://www.youtube.com/watch?v=032SfEBFIJs&t=913s).
+ await _eventPubService.PublishEvent(new NameIndexed(nameEntry.Title, nameEntry.Meaning));
}
}
}
\ No newline at end of file
diff --git a/Application/Services/SearchService.cs b/Application/Services/SearchService.cs
index 4c38f93..600f94d 100644
--- a/Application/Services/SearchService.cs
+++ b/Application/Services/SearchService.cs
@@ -1,8 +1,9 @@
using Application.Mappers;
using Core.Dto.Response;
-using Core.Entities.NameEntry;
-using Core.Enums;
+using Core.Entities;
using Core.Repositories;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Enums;
namespace Application.Services
{
@@ -21,18 +22,18 @@ public async Task> AutoComplete(string query)
if(query.Length > 1)
{
- namesResult = await _namesRepository.FindByNameStartingWithAndState(query, State.PUBLISHED);
+ namesResult = await _namesRepository.FindByTitleStartingWithAndState(query, State.PUBLISHED);
}
- var namesContainingQuery = await _namesRepository.FindNameEntryByNameContainingAndState(query, State.PUBLISHED);
+ var namesContainingQuery = await _namesRepository.FindEntryByTitleContainingAndState(query, State.PUBLISHED);
namesResult.UnionWith(namesContainingQuery);
- return new HashSet(namesResult.Select(n => n.Name));
+ return new HashSet(namesResult.Select(n => n.Title));
}
public async Task GetName(string searchTerm)
{
- var result = await _namesRepository.FindByNameAndState(searchTerm, State.PUBLISHED);
+ var result = await _namesRepository.FindByTitleAndState(searchTerm, State.PUBLISHED);
return result?.MapToDto();
}
@@ -48,23 +49,23 @@ public async Task GetNamesMetadata()
public async Task> Search(string searchTerm)
{
- var exactFound = await _namesRepository.FindByNameAndState(searchTerm, State.PUBLISHED);
+ var exactFound = await _namesRepository.FindByTitleAndState(searchTerm, State.PUBLISHED);
if (exactFound != null)
{
return new NameEntry[] { exactFound };
}
- var startingWithSearchTerm = await _namesRepository.FindByNameStartingWithAndState(searchTerm, State.PUBLISHED);
+ var startingWithSearchTerm = await _namesRepository.FindByTitleStartingWithAndState(searchTerm, State.PUBLISHED);
if (startingWithSearchTerm.Any())
{
return startingWithSearchTerm;
}
var possibleFound = new HashSet();
- possibleFound.UnionWith(await _namesRepository.FindNameEntryByNameContainingAndState(searchTerm, State.PUBLISHED));
- possibleFound.UnionWith(await _namesRepository.FindNameEntryByVariantsContainingAndState(searchTerm, State.PUBLISHED));
- possibleFound.UnionWith(await _namesRepository.FindNameEntryByMeaningContainingAndState(searchTerm, State.PUBLISHED));
- possibleFound.UnionWith(await _namesRepository.FindNameEntryByExtendedMeaningContainingAndState(searchTerm, State.PUBLISHED));
+ possibleFound.UnionWith(await _namesRepository.FindEntryByTitleContainingAndState(searchTerm, State.PUBLISHED));
+ possibleFound.UnionWith(await _namesRepository.FindEntryByVariantsContainingAndState(searchTerm, State.PUBLISHED));
+ possibleFound.UnionWith(await _namesRepository.FindEntryByMeaningContainingAndState(searchTerm, State.PUBLISHED));
+ possibleFound.UnionWith(await _namesRepository.FindEntryByExtendedMeaningContainingAndState(searchTerm, State.PUBLISHED));
return possibleFound;
@@ -72,7 +73,7 @@ public async Task> Search(string searchTerm)
public async Task> SearchByStartsWith(string searchTerm)
{
- return await _namesRepository.FindByNameStartingWithAndState(searchTerm, State.PUBLISHED);
+ return await _namesRepository.FindByTitleStartingWithAndState(searchTerm, State.PUBLISHED);
}
}
}
diff --git a/Application/Services/UserService.cs b/Application/Services/UserService.cs
index 3cad646..b6e6529 100644
--- a/Application/Services/UserService.cs
+++ b/Application/Services/UserService.cs
@@ -1,7 +1,7 @@
-using Core.Dto.Request;
-using Core.Dto.Response;
-using Core.Entities;
-using Core.Repositories;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Entities;
+using YorubaOrganization.Core.Repositories;
using BCrypt_ = BCrypt.Net.BCrypt;
namespace Application.Services
diff --git a/Application/Validation/CreateUserValidator.cs b/Application/Validation/CreateUserValidator.cs
index e5df7ee..6c307cf 100644
--- a/Application/Validation/CreateUserValidator.cs
+++ b/Application/Validation/CreateUserValidator.cs
@@ -1,6 +1,6 @@
-using Core.Dto.Response;
-using Core.Enums;
-using FluentValidation;
+using FluentValidation;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Enums;
namespace Application.Validation
{
diff --git a/Application/Validation/EmbeddedVideoValidator.cs b/Application/Validation/EmbeddedVideoValidator.cs
index aa2ca23..2fd3972 100644
--- a/Application/Validation/EmbeddedVideoValidator.cs
+++ b/Application/Validation/EmbeddedVideoValidator.cs
@@ -1,10 +1,5 @@
-using Core.Dto.Request;
-using FluentValidation;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using FluentValidation;
+using YorubaOrganization.Core.Dto.Request;
namespace Application.Validation
{
diff --git a/Application/Validation/EtymologyValidator.cs b/Application/Validation/EtymologyValidator.cs
index 02371e0..5f42349 100644
--- a/Application/Validation/EtymologyValidator.cs
+++ b/Application/Validation/EtymologyValidator.cs
@@ -1,10 +1,5 @@
-using Core.Dto.Request;
-using FluentValidation;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using FluentValidation;
+using YorubaOrganization.Core.Dto.Request;
namespace Application.Validation
{
diff --git a/Application/Validation/GeoLocationValidator.cs b/Application/Validation/GeoLocationValidator.cs
index 233e46e..19aa950 100644
--- a/Application/Validation/GeoLocationValidator.cs
+++ b/Application/Validation/GeoLocationValidator.cs
@@ -1,6 +1,6 @@
-using Core.Dto.Request;
-using Core.Repositories;
-using FluentValidation;
+using FluentValidation;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Repositories;
namespace Application.Validation
{
diff --git a/Application/Validation/UpdateUserValidator.cs b/Application/Validation/UpdateUserValidator.cs
index a6e3648..d2599fe 100644
--- a/Application/Validation/UpdateUserValidator.cs
+++ b/Application/Validation/UpdateUserValidator.cs
@@ -1,6 +1,6 @@
-using Core.Dto.Request;
-using Core.Enums;
-using FluentValidation;
+using FluentValidation;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Enums;
namespace Application.Validation
{
diff --git a/Core/Cache/IRecentIndexesCache.cs b/Core/Cache/IRecentIndexesCache.cs
deleted file mode 100644
index f533cd7..0000000
--- a/Core/Cache/IRecentIndexesCache.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Core.Cache
-{
- public interface IRecentIndexesCache : ISetBasedCache
- {
- }
-}
\ No newline at end of file
diff --git a/Core/Cache/IRecentSearchesCache.cs b/Core/Cache/IRecentSearchesCache.cs
deleted file mode 100644
index 73d9bd3..0000000
--- a/Core/Cache/IRecentSearchesCache.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Cache
-{
- public interface IRecentSearchesCache : ISetBasedCache
- {
- Task> GetMostPopular();
- }
-}
\ No newline at end of file
diff --git a/Core/Cache/ISetBasedCache.cs b/Core/Cache/ISetBasedCache.cs
deleted file mode 100644
index 581739e..0000000
--- a/Core/Cache/ISetBasedCache.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Core.Cache
-{
- public interface ISetBasedCache
- {
- Task> Get();
- Task Stack(T item);
- Task Remove(T item);
- }
-}
diff --git a/Core/Cache/ISimpleCache.cs b/Core/Cache/ISimpleCache.cs
deleted file mode 100644
index d943fb8..0000000
--- a/Core/Cache/ISimpleCache.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Core.Cache
-{
- public interface ISimpleCache
- {
- Task SetAsync(string key, T value, TimeSpan? expiry = null);
- Task GetAsync(string key);
- }
-}
diff --git a/Core/Core.csproj b/Core/Core.csproj
index a6b9113..f754c70 100644
--- a/Core/Core.csproj
+++ b/Core/Core.csproj
@@ -4,4 +4,7 @@
enable
enable
+
+
+
\ No newline at end of file
diff --git a/Core/Dto/CharacterSeparatedString.cs b/Core/Dto/CharacterSeparatedString.cs
deleted file mode 100644
index 57eb98b..0000000
--- a/Core/Dto/CharacterSeparatedString.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace Core.Dto
-{
- public abstract class CharacterSeparatedString where T : CharacterSeparatedString
- {
- protected string SeparatorOut { get; init; }
- protected char SeparatorIn { get; init; }
- protected readonly string value;
-
- public CharacterSeparatedString(string? value)
- {
- this.value = value?.Trim() ?? string.Empty;
- }
-
- public override string ToString()
- {
- return value;
- }
-
- public static implicit operator CharacterSeparatedString(List list)
- {
- var anObject = (CharacterSeparatedString) Activator.CreateInstance(typeof(T), string.Empty);
- return (CharacterSeparatedString) Activator.CreateInstance(typeof(T), string.Join(anObject.SeparatorOut, list));
-
- }
-
- public static implicit operator List(CharacterSeparatedString charSeparatedString)
- {
- return charSeparatedString.value
- .Split(charSeparatedString.SeparatorIn)
- .Select(item => item.Trim())
- .Where(item => !string.IsNullOrEmpty(item))
- .ToList();
- }
- }
-}
diff --git a/Core/Dto/CommaSeparatedString.cs b/Core/Dto/CommaSeparatedString.cs
deleted file mode 100644
index a272f4e..0000000
--- a/Core/Dto/CommaSeparatedString.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Core.Dto
-{
- public class CommaSeparatedString : CharacterSeparatedString
- {
- public CommaSeparatedString(string? value) : base(value)
- {
- SeparatorIn = ',';
- SeparatorOut = ", ";
- }
- }
-}
diff --git a/Core/Dto/HyphenSeparatedString.cs b/Core/Dto/HyphenSeparatedString.cs
deleted file mode 100644
index c3e5426..0000000
--- a/Core/Dto/HyphenSeparatedString.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-
-namespace Core.Dto
-{
- public class HyphenSeparatedString : CharacterSeparatedString
- {
- public HyphenSeparatedString(string? value) : base(value)
- {
- SeparatorIn = '-';
- SeparatorOut = "-";
- }
-
-
- }
-}
diff --git a/Core/Dto/Request/CreateGeoLocationDto.cs b/Core/Dto/Request/CreateGeoLocationDto.cs
deleted file mode 100644
index e334b9c..0000000
--- a/Core/Dto/Request/CreateGeoLocationDto.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Core.Dto.Request
-{
- public record CreateGeoLocationDto(string Place, string Region)
- {
- }
-}
diff --git a/Core/Dto/Request/CreateNameDto.cs b/Core/Dto/Request/CreateNameDto.cs
index 59cefb8..6bfcecb 100644
--- a/Core/Dto/Request/CreateNameDto.cs
+++ b/Core/Dto/Request/CreateNameDto.cs
@@ -1,6 +1,4 @@
-using Core.Dto.Request;
-
-namespace Api.Model.In
+namespace Core.Dto.Request
{
public class CreateNameDto : NameDto
{
diff --git a/Core/Dto/Request/CreateNameFeedbackDto.cs b/Core/Dto/Request/CreateNameFeedbackDto.cs
index 9ee0f0f..d068866 100644
--- a/Core/Dto/Request/CreateNameFeedbackDto.cs
+++ b/Core/Dto/Request/CreateNameFeedbackDto.cs
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
-namespace Api.Model.Request
+namespace Core.Dto.Request
{
public record CreateNameFeedbackDto([Required] string Name, [Required(ErrorMessage = "Cannot give an empty feedback")] string Feedback);
}
diff --git a/Core/Dto/Request/CreateSuggestedNameDto.cs b/Core/Dto/Request/CreateSuggestedNameDto.cs
index de0cb9c..3b72c55 100644
--- a/Core/Dto/Request/CreateSuggestedNameDto.cs
+++ b/Core/Dto/Request/CreateSuggestedNameDto.cs
@@ -1,4 +1,6 @@
-namespace Core.Dto.Request;
+using YorubaOrganization.Core.Dto.Request;
+
+namespace Core.Dto.Request;
public record CreateSuggestedNameDto
{
diff --git a/Core/Dto/Request/CreateUserDto.cs b/Core/Dto/Request/CreateUserDto.cs
deleted file mode 100644
index 93afbab..0000000
--- a/Core/Dto/Request/CreateUserDto.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-
-namespace Core.Dto.Response
-{
- public record CreateUserDto
- {
- public string? Username { get; set; }
- public string? Password { get; set; }
- public string? Email { get; set; }
-
- public string[] Roles { get; set; }
-
- public string? CreatedBy { get; set; }
- }
-}
diff --git a/Core/Dto/Request/EmbeddedVideoDto.cs b/Core/Dto/Request/EmbeddedVideoDto.cs
deleted file mode 100644
index 036fbbf..0000000
--- a/Core/Dto/Request/EmbeddedVideoDto.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Dto.Request
-{
- public record EmbeddedVideoDto(string VideoId, string Caption)
- {
- }
-}
-
diff --git a/Core/Dto/Request/EtymologyDto.cs b/Core/Dto/Request/EtymologyDto.cs
deleted file mode 100644
index cb1a815..0000000
--- a/Core/Dto/Request/EtymologyDto.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Core.Dto.Request
-{
- ///
- /// TODO: Add field validations
- ///
- public record EtymologyDto(string Part, string Meaning)
- {
- }
-
-}
diff --git a/Core/Dto/Request/NameDto.cs b/Core/Dto/Request/NameDto.cs
index beb674e..43d8698 100644
--- a/Core/Dto/Request/NameDto.cs
+++ b/Core/Dto/Request/NameDto.cs
@@ -1,4 +1,7 @@
-using Core.Enums;
+using YorubaOrganization.Core.Dto;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Entities.Partials;
+using YorubaOrganization.Core.Enums;
namespace Core.Dto.Request
{
@@ -20,6 +23,21 @@ public abstract class NameDto
public CommaSeparatedString? Variants { get; set; }
+ public List VariantsV2 {
+ get
+ {
+ return Variants == null ? [] : ((List)Variants).Select(v => new Variant(v)).ToList();
+ }
+ }
+
+ public List MediaLinks
+ {
+ get
+ {
+ return Media == null ? [] : ((List)Media).Select(m => new MediaLink(m)).ToList();
+ }
+ }
+
public CommaSeparatedString? Morphology { get; set; }
public CommaSeparatedString? Media { get; set; }
diff --git a/Core/Dto/Request/UpdateUserDto.cs b/Core/Dto/Request/UpdateUserDto.cs
deleted file mode 100644
index ee762b5..0000000
--- a/Core/Dto/Request/UpdateUserDto.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Dto.Request
-{
- public record UpdateUserDto (string? Username, string? Password, string[]? Roles, string? UpdatedBy)
- {
-
- }
-}
diff --git a/Core/Dto/Response/FeedbackDto.cs b/Core/Dto/Response/FeedbackDto.cs
deleted file mode 100644
index 5aae22a..0000000
--- a/Core/Dto/Response/FeedbackDto.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Core.Dto.Response
-{
- public record FeedbackDto(string Id, string Name, string Feedback, DateTime SubmittedAt)
- {
- }
-}
diff --git a/Core/Dto/Response/GeoLocationDto.cs b/Core/Dto/Response/GeoLocationDto.cs
deleted file mode 100644
index 99441ae..0000000
--- a/Core/Dto/Response/GeoLocationDto.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Core.Dto.Response
-{
- public record GeoLocationDto(string Id, string Place, string Region)
- {
- public override string ToString()
- {
- return Place;
- }
- }
-}
diff --git a/Core/Dto/Response/NameEntryDto.cs b/Core/Dto/Response/NameEntryDto.cs
index 44325d6..b0000e2 100644
--- a/Core/Dto/Response/NameEntryDto.cs
+++ b/Core/Dto/Response/NameEntryDto.cs
@@ -1,5 +1,7 @@
-using Core.Dto.Request;
-using Core.Enums;
+using YorubaOrganization.Core.Dto;
+using YorubaOrganization.Core.Dto.Request;
+using YorubaOrganization.Core.Dto.Response;
+using YorubaOrganization.Core.Enums;
namespace Core.Dto.Response
{
diff --git a/Core/Dto/Response/NameFeedbackDto.cs b/Core/Dto/Response/NameFeedbackDto.cs
new file mode 100644
index 0000000..7e2f0db
--- /dev/null
+++ b/Core/Dto/Response/NameFeedbackDto.cs
@@ -0,0 +1,6 @@
+namespace Core.Dto.Response
+{
+ public record NameFeedbackDto(string Id, string Name, string Feedback, DateTime SubmittedAt)
+ {
+ }
+}
diff --git a/Core/Dto/Response/RecentStats.cs b/Core/Dto/Response/RecentStats.cs
deleted file mode 100644
index 3904200..0000000
--- a/Core/Dto/Response/RecentStats.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Core.Dto.Response
-{
- public record RecentStats
- {
- [JsonPropertyName("search")]
- public string[] LatestSearches { get; init; }
-
- [JsonPropertyName("index")]
- public string[] LatestAdditions { get; init; }
-
- [JsonPropertyName("popular")]
- public string[] MostPopular { get; init; }
-
- public RecentStats()
- {
- LatestSearches = new string[0];
- LatestAdditions = new string[0];
- MostPopular = new string[0];
- }
- }
-}
diff --git a/Core/Dto/Response/SearchMetadataDto.cs b/Core/Dto/Response/SearchMetadataDto.cs
deleted file mode 100644
index 7bb5a51..0000000
--- a/Core/Dto/Response/SearchMetadataDto.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Dto.Response
-{
- public class SearchMetadataDto
- {
- public int TotalPublishedNames { get; set; }
- }
-}
diff --git a/Core/Dto/Response/SuggestedNameDto.cs b/Core/Dto/Response/SuggestedNameDto.cs
index c1d1cc8..17d356b 100644
--- a/Core/Dto/Response/SuggestedNameDto.cs
+++ b/Core/Dto/Response/SuggestedNameDto.cs
@@ -1,4 +1,6 @@
-namespace Core.Dto.Response;
+using YorubaOrganization.Core.Dto.Response;
+
+namespace Core.Dto.Response;
public record SuggestedNameDto
{
diff --git a/Core/Dto/Response/UserDto.cs b/Core/Dto/Response/UserDto.cs
deleted file mode 100644
index 6a9c157..0000000
--- a/Core/Dto/Response/UserDto.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Core.Dto.Response
-{
- public record UserDto
- {
- public string Email { get; set; }
- public string? Username { get; set; }
- public string[] Roles { get; set; }
- }
-}
diff --git a/Core/Entities/BaseEntity.cs b/Core/Entities/BaseEntity.cs
deleted file mode 100644
index 1fd9f47..0000000
--- a/Core/Entities/BaseEntity.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-
-namespace Core.Entities
-{
- public abstract class BaseEntity
- {
- public BaseEntity()
- {
- CreatedAt = DateTime.UtcNow;
- UpdatedAt = CreatedAt;
- }
-
- public string Id { get; set; }
- public DateTime CreatedAt { get; set; }
-
- public string? CreatedBy { get; set; }
- public DateTime UpdatedAt { get; set; }
- public string? UpdatedBy { get; set; }
- }
-}
diff --git a/Core/Entities/GeoLocation.cs b/Core/Entities/GeoLocation.cs
deleted file mode 100644
index f0465f4..0000000
--- a/Core/Entities/GeoLocation.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Core.Entities
-{
- public class GeoLocation : BaseEntity
- {
- public string Place { get; set; }
-
- // TODO Minor: Get Kola's brief about why this is separated into Place and Region.
- // TODO Minor: Is the Region which is not currently used anywhere of any use?
- public string Region { get; set; }
-
-
- public GeoLocation() { }
-
- public GeoLocation(string place, string region)
- {
- Place = place;
- Region = region;
- }
- }
-}
\ No newline at end of file
diff --git a/Core/Entities/NameEntry.cs b/Core/Entities/NameEntry.cs
new file mode 100644
index 0000000..7438491
--- /dev/null
+++ b/Core/Entities/NameEntry.cs
@@ -0,0 +1,16 @@
+using YorubaOrganization.Core.Entities;
+
+namespace Core.Entities;
+
+public class NameEntry : DictionaryEntry
+{
+ public string Meaning { get; set; }
+ public string? ExtendedMeaning { get; set; }
+ public List FamousPeople { get; set; }
+
+ protected override void InitializeLists()
+ {
+ base.InitializeLists();
+ FamousPeople = [];
+ }
+}
\ No newline at end of file
diff --git a/Core/Entities/NameEntry/Collections/EmbeddedVideo.cs b/Core/Entities/NameEntry/Collections/EmbeddedVideo.cs
deleted file mode 100644
index 98e1183..0000000
--- a/Core/Entities/NameEntry/Collections/EmbeddedVideo.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Core.Entities.NameEntry.Collections;
-
-public class EmbeddedVideo : BaseEntity
-{
- public EmbeddedVideo(string videoId, string caption)
- {
- VideoId = videoId;
- Caption = caption;
- }
-
- public string VideoId { get; set; }
- public string Caption { get; set; }
-
-}
diff --git a/Core/Entities/NameEntry/Collections/Etymology.cs b/Core/Entities/NameEntry/Collections/Etymology.cs
deleted file mode 100644
index 48e01e8..0000000
--- a/Core/Entities/NameEntry/Collections/Etymology.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Core.Entities.NameEntry.Collections;
-
-public class Etymology : BaseEntity
-{
- public string Part { get; set; }
- public string Meaning { get; set; }
-
- public Etymology(string part, string meaning)
- {
- Part = part;
- Meaning = meaning;
- }
-}
\ No newline at end of file
diff --git a/Core/Entities/NameEntry/Collections/Feedback.cs b/Core/Entities/NameEntry/Collections/Feedback.cs
deleted file mode 100644
index 65232bf..0000000
--- a/Core/Entities/NameEntry/Collections/Feedback.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Core.Entities.NameEntry.Collections
-{
- ///
- /// Feedback from anonymous website users.
- /// TODO Later: We can capture their name or email address going forward (in the universal SubmittedBy field)
- ///
- public class Feedback : BaseEntity
- {
- public string? Content { get; set; }
-
- public Feedback() { }
-
- public Feedback(string content)
- {
- Content = content;
- }
- }
-}
diff --git a/Core/Entities/NameEntry/NameEntry.cs b/Core/Entities/NameEntry/NameEntry.cs
deleted file mode 100644
index a4f5142..0000000
--- a/Core/Entities/NameEntry/NameEntry.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using Core.Entities.NameEntry.Collections;
-using Core.Enums;
-
-namespace Core.Entities.NameEntry;
-
-public class NameEntry : BaseEntity, IComparable
-{
- public string Name { get; set; }
-
- public string? Pronunciation { get; set; }
- // Only 3 values exist in the DB for this field at the moment. However, Kola would like to retain it.
- public string? IpaNotation { get; set; }
- public string Meaning { get; set; }
- public string? ExtendedMeaning { get; set; }
- public List Morphology { get; set; }
- public List Media { get; set; }
- public State State { get; set; }
-
- // Note: Did not migrate TonalMark, Tags, InOtherLanguages intentionally since all values are null in the database (no admin boxes for them)
- public List Etymology { get; set; }
- public List Videos { get; set; }
- public List GeoLocation { get; set; }
-
- public List FamousPeople { get; set; }
-
- public List Syllables { get; set; }
-
- public List Variants { get; set; }
-
- ///
- /// When the current entry is edited, the edited version will be stored here until it is published
- ///
- public NameEntry? Modified { get; set; }
-
- ///
- /// An item is added in here if an attempt is made to create a name which already exists.
- /// Only adding in this feature because it exists in the Java version.
- /// There is no functional application of these objects at the moment.
- ///
- public List Duplicates { get; set; }
- public List Feedbacks { get; set; }
-
-
- private void InitializeLists()
- {
- Etymology = new List();
- Videos = new List();
- Duplicates = new List();
- Feedbacks = new List();
-
- Syllables = new List();
- FamousPeople = new List();
- Variants = new List();
- Morphology = new List();
- Media = new List();
-
- GeoLocation = new List();
- }
-
- public NameEntry(string name, string meaning)
- {
- Name = name ?? throw new ArgumentNullException(nameof(name));
- Meaning = meaning ?? throw new ArgumentNullException(nameof(meaning));
-
- InitializeLists();
- }
- public NameEntry()
- {
- InitializeLists();
- }
-
- public int CompareTo(NameEntry? other)
- {
- return Name.CompareTo(other?.Name);
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(Name);
- }
-
- public override bool Equals(object? obj)
- {
- // Standard equality checks
- if (obj is not NameEntry)
- {
- return false;
- }
-
- NameEntry other = (NameEntry)obj;
-
- return Name == other.Name;
- }
-}
\ No newline at end of file
diff --git a/Core/Entities/SuggestedName.cs b/Core/Entities/SuggestedName.cs
index 69347d7..cf5d6ed 100644
--- a/Core/Entities/SuggestedName.cs
+++ b/Core/Entities/SuggestedName.cs
@@ -1,4 +1,6 @@
-namespace Core.Entities
+using YorubaOrganization.Core.Entities;
+
+namespace Core.Entities
{
public class SuggestedName : BaseEntity
{
diff --git a/Core/Entities/User.cs b/Core/Entities/User.cs
deleted file mode 100644
index ea41ead..0000000
--- a/Core/Entities/User.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Core.Entities
-{
- public class User : BaseEntity
- {
- public string? Email { get; set; }
- public string? Username { get; set; }
- public string? Password { get; set; }
- public List Roles { get; set; }
-
- public User()
- {
- Roles = new List();
- }
- }
-}
diff --git a/Core/Enums/Role.cs b/Core/Enums/Role.cs
deleted file mode 100644
index b39a49b..0000000
--- a/Core/Enums/Role.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Core.Enums
-{
- public enum Role
- {
- ADMIN,
- PRO_LEXICOGRAPHER,
- BASIC_LEXICOGRAPHER
- }
-}
diff --git a/Core/Enums/State.cs b/Core/Enums/State.cs
deleted file mode 100644
index 580c08e..0000000
--- a/Core/Enums/State.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Core.Enums;
-
-public enum State
-{
- NEW,
- UNPUBLISHED,
- PUBLISHED,
- MODIFIED
-}
\ No newline at end of file
diff --git a/Core/Events/ExactNameSearched.cs b/Core/Events/ExactNameSearched.cs
deleted file mode 100644
index 0de0ffb..0000000
--- a/Core/Events/ExactNameSearched.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Events
-{
- public record ExactNameSearched(string SearchTerm)
- {
-
- }
-}
\ No newline at end of file
diff --git a/Core/Events/IEventPubService.cs b/Core/Events/IEventPubService.cs
deleted file mode 100644
index c323f80..0000000
--- a/Core/Events/IEventPubService.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Events
-{
- public interface IEventPubService
- {
- Task PublishEvent(T theEvent);
- }
-}
diff --git a/Core/Events/NameDeleted.cs b/Core/Events/NameDeleted.cs
deleted file mode 100644
index 4816490..0000000
--- a/Core/Events/NameDeleted.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace Core.Events;
-
-public record class NameDeleted(string Name)
-{
-}
\ No newline at end of file
diff --git a/Core/Events/NameEntryNameUpdated.cs b/Core/Events/NameEntryNameUpdated.cs
deleted file mode 100644
index 0588536..0000000
--- a/Core/Events/NameEntryNameUpdated.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Core.Events
-{
- public record NameEntryNameUpdated(string OriginalName, string NewName)
- {
- }
-}
\ No newline at end of file
diff --git a/Core/Events/NameIndexed.cs b/Core/Events/NameIndexed.cs
index 52f6a65..30cd03c 100644
--- a/Core/Events/NameIndexed.cs
+++ b/Core/Events/NameIndexed.cs
@@ -1,6 +1,8 @@
-namespace Core.Events
+using MediatR;
+
+namespace Core.Events
{
- public record NameIndexed(string Name, string Meaning)
+ public record NameIndexed(string Name, string Meaning) : INotification
{
}
}
diff --git a/Core/Events/NonExistingNameUpdateAttempted.cs b/Core/Events/NonExistingNameUpdateAttempted.cs
deleted file mode 100644
index a9ae1df..0000000
--- a/Core/Events/NonExistingNameUpdateAttempted.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Core.Events
-{
- public record NonExistingNameUpdateAttempted(string Name)
- {
- }
-}
\ No newline at end of file
diff --git a/Core/Repositories/IEtymologyRepository.cs b/Core/Repositories/IEtymologyRepository.cs
deleted file mode 100644
index 16fd445..0000000
--- a/Core/Repositories/IEtymologyRepository.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Core.Repositories
-{
- public interface IEtymologyRepository
- {
- Task> GetLatestMeaningOf(IEnumerable parts);
- }
-}
diff --git a/Core/Repositories/IGeoLocationsRepository.cs b/Core/Repositories/IGeoLocationsRepository.cs
deleted file mode 100644
index 3f826ec..0000000
--- a/Core/Repositories/IGeoLocationsRepository.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Core.Entities;
-
-namespace Core.Repositories
-{
- public interface IGeoLocationsRepository
- {
- Task> GetAll();
-
- Task FindByPlace(string place);
- Task FindByPlaceAndRegion(string region, string place);
- Task Create(GeoLocation geoLocation);
- Task Delete(string id, string place);
- }
-}
diff --git a/Core/Repositories/INameEntryFeedbackRepository.cs b/Core/Repositories/INameEntryFeedbackRepository.cs
index f2f9876..b66224f 100644
--- a/Core/Repositories/INameEntryFeedbackRepository.cs
+++ b/Core/Repositories/INameEntryFeedbackRepository.cs
@@ -1,13 +1,14 @@
using Core.Dto.Response;
+
namespace Core.Repositories
{
public interface INameEntryFeedbackRepository
{
- Task> FindAllAsync();
- Task> FindByNameAsync(string name);
+ Task> FindAllAsync();
+ Task> FindByNameAsync(string name);
Task AddFeedbackByNameAsync(string name, string feedbackContent);
Task DeleteAllFeedbackForNameAsync(string name);
- Task GetFeedbackByIdAsync(string feedbackId);
+ Task GetFeedbackByIdAsync(string feedbackId);
Task DeleteFeedbackAsync(string name, string feedbackId);
}
}
diff --git a/Core/Repositories/INameEntryRepository.cs b/Core/Repositories/INameEntryRepository.cs
index 29b9346..fbec837 100644
--- a/Core/Repositories/INameEntryRepository.cs
+++ b/Core/Repositories/INameEntryRepository.cs
@@ -1,54 +1,11 @@
-using Core.Dto.Response;
-using Core.Entities.NameEntry;
-using Core.Enums;
-using System.Linq.Expressions;
+using Core.Entities;
+using YorubaOrganization.Core.Enums;
+using YorubaOrganization.Core.Repositories;
namespace Core.Repositories
{
- public interface INameEntryRepository
+ public interface INameEntryRepository : IDictionaryEntryRepository
{
- Task FindById(string id);
- Task Create(NameEntry newName);
- Task Create(List newName);
- Task DeleteAll();
-
- // TODO Later: This method should not be accessible. Too heavy on the DB
- Task> ListAll();
-
- Task FindByName(string name);
- Task> FindByNames(string[] names);
-
- Task> FindByState(State state);
-
- Task> FindByNameStartingWithAndState(string alphabet, State state);
-
- Task> FindByNameStartingWithAnyAndState(IEnumerable searchTerms, State state);
-
- Task> FindNameEntryByNameContainingAndState(string name, State state);
-
- Task> FindNameEntryByVariantsContainingAndState(string name, State state);
-
- Task> FindNameEntryByMeaningContainingAndState(string name, State state);
-
- Task> FindNameEntryByExtendedMeaningContainingAndState(string name, State state);
-
- Task FindByNameAndState(string name, State state);
-
- Task CountByState(State state);
-
- Task Delete(string name);
-
- Task DeleteMany(string[] name);
-
- Task DeleteByNameAndState(string name, State state);
-
- Task Update(string originalName, NameEntry newEntry);
-
- Task CountWhere(Expression> filter);
-
- Task> List(int pageNumber, int pageSize, State? state, string? submittedBy);
-
- Task GetMetadata();
- Task> GetAllNames(State? state, string? submittedBy);
+ Task> FindEntryByExtendedMeaningContainingAndState(string title, State state);
}
}
diff --git a/Core/Repositories/IUserRepository.cs b/Core/Repositories/IUserRepository.cs
deleted file mode 100644
index 4864243..0000000
--- a/Core/Repositories/IUserRepository.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Core.Dto.Request;
-using Core.Dto.Response;
-using Core.Entities;
-
-namespace Core.Repositories
-{
- public interface IUserRepository
- {
- Task GetUserByEmail(string email);
- Task Create(User newUser);
- Task DeleteBy(string email);
- Task Update(string email, UpdateUserDto update);
- Task> List();
- Task CountUsers();
- }
-}
diff --git a/Core/StringObjectConverters/CharacterSeparatedStringConverter.cs b/Core/StringObjectConverters/CharacterSeparatedStringConverter.cs
index 93a57c1..972aa88 100644
--- a/Core/StringObjectConverters/CharacterSeparatedStringConverter.cs
+++ b/Core/StringObjectConverters/CharacterSeparatedStringConverter.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
using System.Text.Json;
-using Core.Dto;
+using YorubaOrganization.Core.Dto;
namespace Core.StringObjectConverters
{
diff --git a/Core/StringObjectConverters/CommaSeparatedStringConverter.cs b/Core/StringObjectConverters/CommaSeparatedStringConverter.cs
index 6f5db6a..be6bb02 100644
--- a/Core/StringObjectConverters/CommaSeparatedStringConverter.cs
+++ b/Core/StringObjectConverters/CommaSeparatedStringConverter.cs
@@ -1,4 +1,4 @@
-using Core.Dto;
+using YorubaOrganization.Core.Dto;
namespace Core.StringObjectConverters
{
diff --git a/Core/StringObjectConverters/HyphenSeparatedStringConverter.cs b/Core/StringObjectConverters/HyphenSeparatedStringConverter.cs
index 27d0405..cb64d5f 100644
--- a/Core/StringObjectConverters/HyphenSeparatedStringConverter.cs
+++ b/Core/StringObjectConverters/HyphenSeparatedStringConverter.cs
@@ -1,4 +1,4 @@
-using Core.Dto;
+using YorubaOrganization.Core.Dto;
namespace Core.StringObjectConverters
{
diff --git a/Core/Utilities/DiacriticsNormalizer.cs b/Core/Utilities/DiacriticsNormalizer.cs
deleted file mode 100644
index 5fb35ed..0000000
--- a/Core/Utilities/DiacriticsNormalizer.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System.Globalization;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace Core.Utilities
-{
- public static class DiacriticsNormalizer
- {
- const char a = 'a', e = 'e', i = 'i', o = 'o', u = 'u';
- static readonly Dictionary vowelMap = new()
- {
- { 'á', a },
- { 'à', a },
- { 'a', a },
- { 'é', e },
- { 'è', e },
- { 'e', e },
- { 'ẹ', e },
- { 'í', i },
- { 'ì', i },
- { 'i', i },
- { 'ó', o },
- { 'ò', o },
- { 'o', o },
- { 'ọ', o },
- { 'ú', u },
- { 'ù', u },
- { 'u', u }
- };
-
-
- static readonly Dictionary vowelPatterns = new()
- {
- // "\\p{Mn}?" means zero or one nonspacing unicode mark. It could occur after any vowel.
- { 'a', "[aáà]\\p{Mn}?" },
- { 'e', "[eéèẹ]\\p{Mn}?" },
- { 'i', "[iíì]\\p{Mn}?" },
- { 'o', "[oóòọ]\\p{Mn}?" },
- { 'u', "[uúù]\\p{Mn}?" }
- };
-
- private static string RemoveDiacriticsAndSimplify(this string text)
- {
- var decomposed = text.Normalize(NormalizationForm.FormD);
- var stringBuilder = new StringBuilder();
-
- foreach (var c in decomposed)
- {
- if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
- {
- if (vowelMap.TryGetValue(c, out var simpleVowel))
- {
- stringBuilder.Append(simpleVowel);
- }
- else
- {
- stringBuilder.Append(c);
- }
- }
- }
-
- return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
- }
-
- public static string ReplaceYorubaVowelsWithPattern(this string term)
- {
- term = RemoveDiacriticsAndSimplify(term);
-
- return string.Concat(term.Select(c =>
- vowelPatterns.TryGetValue(c, out var pattern) ? pattern : Regex.Escape(c.ToString())
- ));
- }
- }
-}
diff --git a/Infrastructure.MongoDB/Infrastructure.MongoDB.csproj b/Infrastructure.MongoDB/Infrastructure.MongoDB.csproj
deleted file mode 100644
index fedebeb..0000000
--- a/Infrastructure.MongoDB/Infrastructure.MongoDB.csproj
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- net8.0
- enable
- enable
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Infrastructure.MongoDB/Repositories/MongoDBRepository.cs b/Infrastructure.MongoDB/Repositories/MongoDBRepository.cs
deleted file mode 100644
index 6fae029..0000000
--- a/Infrastructure.MongoDB/Repositories/MongoDBRepository.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using MongoDB.Driver;
-
-namespace Infrastructure.MongoDB.Repositories
-{
- public abstract class MongoDBRepository
- {
- protected static T SetCollationPrimary(dynamic dbCommandOption)
- {
- dbCommandOption.Collation = new Collation("en", strength: CollationStrength.Primary);
- return (T)dbCommandOption;
- }
- protected static T SetCollationSecondary(dynamic dbCommandOption)
- {
- dbCommandOption.Collation = new Collation("en", strength: CollationStrength.Secondary);
- return (T)dbCommandOption;
- }
- }
-}
\ No newline at end of file
diff --git a/Infrastructure.MongoDB/Repositories/NameEntryRepository.cs b/Infrastructure.MongoDB/Repositories/NameEntryRepository.cs
deleted file mode 100644
index 73b5ee1..0000000
--- a/Infrastructure.MongoDB/Repositories/NameEntryRepository.cs
+++ /dev/null
@@ -1,316 +0,0 @@
-using Core.Dto.Response;
-using Core.Entities.NameEntry;
-using Core.Enums;
-using Core.Events;
-using Core.Repositories;
-using Core.Utilities;
-using MongoDB.Bson;
-using MongoDB.Driver;
-using System.Linq.Expressions;
-
-namespace Infrastructure.MongoDB.Repositories;
-
-public class NameEntryRepository : MongoDBRepository, INameEntryRepository
-{
- private readonly IMongoCollection _nameEntryCollection;
- private readonly IEventPubService _eventPubService;
-
- public NameEntryRepository(
- IMongoDatabase database,
- IEventPubService eventPubService)
- {
- _nameEntryCollection = database.GetCollection("NameEntries");
- _eventPubService = eventPubService;
-
- CreateIndexes();
- }
-
- private void CreateIndexes()
- {
- var indexKeys = Builders.IndexKeys.Ascending(x => x.Name);
- var indexOptions = new CreateIndexOptions
- {
- Unique = true,
- Name = "IX_NameEntries_Name_Unique",
- Background = true
- };
- _nameEntryCollection.Indexes.CreateOne(new CreateIndexModel(indexKeys, indexOptions));
- }
-
- public async Task FindById(string id)
- {
- return await _nameEntryCollection.Find(x => x.Id == id).SingleOrDefaultAsync();
- }
-
- public async Task DeleteAll()
- {
- var deleteResult = await _nameEntryCollection.DeleteManyAsync(FilterDefinition.Empty);
- return deleteResult.DeletedCount > 0;
- }
-
-
- public async Task Create(NameEntry entry)
- {
- entry.Id = ObjectId.GenerateNewId().ToString();
- await _nameEntryCollection.InsertOneAsync(entry);
- }
-
- public async Task Create(List entries)
- {
- entries.ForEach(entry => entry.Id = ObjectId.GenerateNewId().ToString()!);
- await _nameEntryCollection.InsertManyAsync(entries);
- }
-
- public async Task CountByState(State state)
- {
- return await CountWhere(ne => ne.State == state);
- }
-
- public async Task Delete(string name)
- {
- var filter = Builders.Filter.Eq("Name", name);
- var options = SetCollationPrimary(new DeleteOptions());
-
- await _nameEntryCollection.DeleteOneAsync(filter, options);
- }
- public async Task DeleteMany(string[] names)
- {
- var filter = Builders.Filter.In("Name", names);
- var options = SetCollationPrimary(new DeleteOptions());
-
- await _nameEntryCollection.DeleteManyAsync(filter, options);
- }
-
- public async Task DeleteByNameAndState(string name, State state)
- {
- var filter = Builders
- .Filter
- .And(Builders.Filter.Eq("Name", name), Builders.Filter.Eq("State", state));
-
- var options = SetCollationPrimary(new DeleteOptions());
-
- var deleteResult = await _nameEntryCollection.DeleteOneAsync(filter, options);
-
- return deleteResult.DeletedCount > 0;
- }
-
- // TODO Hafiz (Later): This is pulling too much data. We should eventually get rid of it.
- public async Task> ListAll()
- {
- var allEntries = await _nameEntryCollection.Find(_ => true).ToListAsync();
- return new HashSet(allEntries);
- }
-
- public async Task FindByName(string name)
- {
- var filter = Builders.Filter.Eq("Name", name);
- var options = SetCollationPrimary(new FindOptions());
-
- return await _nameEntryCollection.Find(filter, options).SingleOrDefaultAsync();
- }
-
- public async Task> FindByNames(string[] names)
- {
- var filter = Builders.Filter.In("Name", names);
- var options = SetCollationPrimary(new FindOptions());
-
- return await _nameEntryCollection.Find(filter, options).ToListAsync();
- }
-
- public async Task FindByNameAndState(string name, State state)
- {
- var options = SetCollationPrimary(new FindOptions());
- return await _nameEntryCollection
- .Find(ne => ne.Name == name && ne.State == state, options)
- .SingleOrDefaultAsync();
- }
-
- public async Task> FindByNameStartingWithAndState(string searchTerm, State state)
- {
- return await FindByNameStartingWithAnyAndState(new string[] { searchTerm }, state);
- }
-
- public async Task> FindByNameStartingWithAnyAndState(IEnumerable searchTerms, State state)
- {
- var regexFilters = searchTerms.Select(term =>
- {
- return Builders.Filter.Regex(ne => ne.Name,
- new BsonRegularExpression($"^{term.ReplaceYorubaVowelsWithPattern()}", "i"));
- });
-
- var namesFilter = Builders.Filter.Or(regexFilters);
- var stateFilter = Builders.Filter.Eq(ne => ne.State, state);
- var combinedFilter = Builders.Filter.And(namesFilter, stateFilter);
-
- var result = await _nameEntryCollection.Find(combinedFilter).ToListAsync();
- return new HashSet(result);
- }
-
-
- public async Task> FindByState(State state)
- {
- return await _nameEntryCollection.Find(ne => ne.State == state).ToListAsync();
- }
-
- public async Task> FindNameEntryByExtendedMeaningContainingAndState(string name, State state)
- {
- var filter = Builders.Filter.Regex(ne => ne.ExtendedMeaning,
- new BsonRegularExpression(name.ReplaceYorubaVowelsWithPattern(), "i")) &
- Builders.Filter.Eq(ne => ne.State, state);
- var result = await _nameEntryCollection.Find(filter).ToListAsync();
- return new HashSet(result);
- }
-
- public async Task> FindNameEntryByMeaningContainingAndState(string name, State state)
- {
- var filter = Builders.Filter.Regex(ne => ne.Name,
- new BsonRegularExpression(name.ReplaceYorubaVowelsWithPattern(), "i"))
- & Builders.Filter.Eq(ne => ne.State, state);
- var result = await _nameEntryCollection.Find(filter).ToListAsync();
- return new HashSet(result);
- }
-
- public async Task> FindNameEntryByNameContainingAndState(string name, State state)
- {
- var filter = Builders.Filter.Regex(ne => ne.Name,
- new BsonRegularExpression(name.ReplaceYorubaVowelsWithPattern(), "i")) &
- Builders.Filter.Eq(ne => ne.State, state);
- var result = await _nameEntryCollection.Find(filter).ToListAsync();
- return new HashSet(result);
- }
-
- public async Task> FindNameEntryByVariantsContainingAndState(string name, State state)
- {
- var regex = new BsonRegularExpression(name.ReplaceYorubaVowelsWithPattern(), "i");
- var filter = Builders.Filter.Regex(ne => ne.Variants, regex) & Builders.Filter.Eq(ne => ne.State, state);
- var result = await _nameEntryCollection.Find(filter).ToListAsync();
- return new HashSet(result);
- }
-
- public async Task Update(string originalName, NameEntry newEntry)
- {
- var filter = Builders.Filter.Eq(ne => ne.Name, originalName);
- var updateStatement = GenerateUpdateStatement(newEntry);
-
- var options = new FindOneAndUpdateOptions
- {
- ReturnDocument = ReturnDocument.After
- };
-
- var updated = await _nameEntryCollection.FindOneAndUpdateAsync(filter, updateStatement, options);
-
- if (updated == null)
- {
- await _eventPubService.PublishEvent(new NonExistingNameUpdateAttempted(originalName));
- }
- else if (originalName != newEntry.Name)
- {
- await _eventPubService.PublishEvent(new NameEntryNameUpdated(originalName, newEntry.Name));
- }
-
- return updated;
- }
-
- public async Task CountWhere(Expression> filter)
- {
- var count = await _nameEntryCollection.CountDocumentsAsync(filter);
- return (int)count;
- }
-
- public async Task> GetAllNames(State? state, string? submittedBy)
- {
- var filterBuilder = Builders.Filter;
- var filter = filterBuilder.Empty;
-
- if (state.HasValue)
- {
- filter &= filterBuilder.Eq(ne => ne.State, state.Value);
- }
-
- if (!string.IsNullOrWhiteSpace(submittedBy))
- {
- filter &= filterBuilder.Eq(ne => ne.CreatedBy, submittedBy.Trim());
- }
-
- var projection = Builders.Projection.Include(ne => ne.Name).Exclude(ne => ne.Id);
-
- var names = await _nameEntryCollection
- .Find(filter)
- .Project(projection)
- .Sort(Builders