repositorydomain-driven-designclean-architecturebusiness-rulesdata-integrity

Data integrity enforcement in Clean architecture: Domain or Data Layer?


I have a project in which I have a 1->N relationship: a person needs to have at least a pet. Because of this rule, we can't have a person without any pets.

There are a PetRepository and a PersonRepository with a delete function.

When deleting a pet, which would be the recommended approach in clean architecture?

1. Check in the domain whether that was the only pet of the person: if true, delete person, if not delete pet

2. Implement the PetRepository delete method in such a way that it enforces data integrity in the DB, for instance by deleting the pet.


Solution

  • a person needs to have at least a pet. Because of this rule, we can't have a person without any pets.

    This sounds like a invariant which belongs to the Person domain concept.

    So to keep the a Person data consistent, I would expect it to have a function where you can remove a pet if it belong to the person. Then in that same function you can check if there are any pets left and if not, delete the person also.

    Like in this pseudo code:

    public class Person 
    { 
       public Collection<Pet> Pets { get; private set; }
       public bool Deleted { get; private set; }
    
        public Result RemovePet(PetId petId) 
        { 
            var pet = Pets.Find(petId);
            if(pet == null) 
            {
                return Result.Failed(PersonErrors.PetNotFound);
            }
            
            Pets.Remove(pet);
            
            if(Pets.Count == 0) 
            {
               Deleted = true;
            }
            
            return Result.Success();
        }  
    }
    

    Now you persist this Person domain model via the Person Repository and the repository should figure out to which table the data should be persisted.