diff --git a/src/Koogle.Application/Services/PersonService.cs b/src/Koogle.Application/Services/PersonService.cs index 3e59355..8040b0b 100644 --- a/src/Koogle.Application/Services/PersonService.cs +++ b/src/Koogle.Application/Services/PersonService.cs @@ -52,6 +52,12 @@ public class PersonService : IPersonService /// public async Task CreateAsync(CreatePersonDto dto, CancellationToken ct = default) { + var existingPerson = await _personRepository.GetByNameAsync(_clubContext.ClubId, dto.Name, ct); + if (existingPerson != null) + { + throw new InvalidOperationException($"Person with name '{dto.Name}' already exists"); + } + var entity = new Person { Id = Guid.NewGuid(), @@ -75,6 +81,12 @@ public class PersonService : IPersonService if (existing.ClubId != _clubContext.ClubId) throw new InvalidOperationException("Person does not belong to current club."); + var existingPerson = await _personRepository.GetByNameAsync(_clubContext.ClubId, dto.Name, ct); + if (existingPerson != null) + { + throw new InvalidOperationException($"Person with name '{dto.Name}' already exists"); + } + existing.Name = dto.Name; existing.PersonStatus = dto.PersonStatus; existing.ModifiedAt = DateTime.UtcNow; diff --git a/src/Koogle.Domain/Interfaces/IPersonRepository.cs b/src/Koogle.Domain/Interfaces/IPersonRepository.cs index 67fd486..957b466 100644 --- a/src/Koogle.Domain/Interfaces/IPersonRepository.cs +++ b/src/Koogle.Domain/Interfaces/IPersonRepository.cs @@ -46,4 +46,13 @@ public interface IPersonRepository /// Cancellation token. /// True if deleted successfully; otherwise, false. Task DeleteAsync(Guid id, CancellationToken ct = default); + + /// + /// Read a person by its name within a specific club context. + /// + /// + /// + /// + /// The person with the name or null + Task GetByNameAsync(Guid clubContextClubId, string dtoName, CancellationToken ct); } diff --git a/src/Koogle.Infrastructure/Repositories/PersonRepository.cs b/src/Koogle.Infrastructure/Repositories/PersonRepository.cs index efc7604..cfb60a0 100644 --- a/src/Koogle.Infrastructure/Repositories/PersonRepository.cs +++ b/src/Koogle.Infrastructure/Repositories/PersonRepository.cs @@ -63,4 +63,13 @@ public class PersonRepository(IDbContextFactory contextFactory) : await context.SaveChangesAsync(ct); return true; } + + /// + public async Task GetByNameAsync(Guid clubContextClubId, string dtoName, CancellationToken ct) + { + await using var context = await contextFactory.CreateDbContextAsync(ct); + var entity = await context.Persons + .FirstOrDefaultAsync(p => p.ClubId == clubContextClubId && p.Name == dtoName && !p.IsDeleted, ct); + return entity; + } }