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;
+ }
}