Index: src/main/java/edu/gjoko/schedlr/services/AppointmentsService.java
===================================================================
--- src/main/java/edu/gjoko/schedlr/services/AppointmentsService.java	(revision 950fa0d7a6b439770e79c885947e9b7d6058b424)
+++ src/main/java/edu/gjoko/schedlr/services/AppointmentsService.java	(revision 77205be723c8b2ffd1ee5618a05e1d12b1cee44a)
@@ -1,15 +1,21 @@
 package edu.gjoko.schedlr.services;
 
-import edu.gjoko.schedlr.entity.Appointment;
-import edu.gjoko.schedlr.entity.Business;
-import edu.gjoko.schedlr.entity.Stakeholder;
+import edu.gjoko.schedlr.dto.AppointmentInfoDto;
+import edu.gjoko.schedlr.entity.*;
 import edu.gjoko.schedlr.exceptions.BlockingTimeException;
+import edu.gjoko.schedlr.mappers.AppointmentInfoDtoBusinessMapper;
+import edu.gjoko.schedlr.mappers.AppointmentInfoDtoCustomerMapper;
 import edu.gjoko.schedlr.repositories.AppointmentRepository;
 import edu.gjoko.schedlr.repositories.ServiceRepository;
-import edu.gjoko.schedlr.repositories.ServiceTypeRepository;
+import edu.gjoko.schedlr.repositories.StakeholderRepository;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import javax.persistence.EntityNotFoundException;
+import javax.security.sasl.AuthenticationException;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @Service
@@ -18,13 +24,18 @@
 
     private final AppointmentRepository appointmentRepository;
+    private final StakeholderRepository stakeholderRepository;
+    private final ServiceRepository serviceRepository;
+    private final AppointmentInfoDtoBusinessMapper appointmentInfoDtoBusinessMapper;
+    private final AppointmentInfoDtoCustomerMapper appointmentInfoDtoCustomerMapper;
 
-    private final ServiceRepository serviceRepository;
 
     public void saveAppointment(Appointment appointment) {
         var service = serviceRepository.findById(appointment.getService().getId()).get();
-        appointment.setEndTime(appointment.getStartTime().plusMinutes(service.getDuration()));
+
+        // remove 1 minute in order to prevent overlapping
+        appointment.setEndTime(appointment.getStartTime().plusMinutes(service.getDuration() - 1));
         List<Appointment> blockingAppointments = appointmentRepository.
                 findBlockingAppointments(
-                        appointment.getBusiness().getId(), appointment.getStartTime(), appointment.getEndTime());
+                        appointment.getService().getBusiness().getId(), appointment.getStartTime(), appointment.getEndTime());
 
         // check to see if there are blocking exceptions
@@ -35,10 +46,64 @@
     }
 
-    public List<Appointment> getAppointmentsByBusiness(Business business) {
-        return appointmentRepository.getAppointmentsByBusiness(business);
+    public List<AppointmentInfoDto> getFutureAppointmentInfoList(Long stakeholderId) {
+        StakeholderType type = stakeholderRepository.findById(stakeholderId).get().getStakeholderType();
+        List<AppointmentInfoDto> appointmentInfoDtoList = new ArrayList<>();
+
+        switch (type) {
+            case BUSINESS_OWNER -> appointmentInfoDtoList = appointmentRepository.findFutureAppointmentsByBusinessOwnerId(stakeholderId, LocalDateTime.now())
+                    .stream()
+                    .map(appointmentInfoDtoBusinessMapper::appointmentToAppointmentInfoDto)
+                    .toList();
+            case CUSTOMER -> appointmentInfoDtoList = appointmentRepository.findFutureAppointmentsByCustomerId(stakeholderId, LocalDateTime.now())
+                    .stream()
+                    .map(appointmentInfoDtoCustomerMapper::appointmentToAppointmentInfoDto)
+                    .toList();
+        }
+
+        return appointmentInfoDtoList;
     }
 
-    private List<Appointment> getAppointmentsByCustomer(Stakeholder stakeholder) {
-        return appointmentRepository.getAppointmentsByCustomer(stakeholder);
+    public List<AppointmentInfoDto> getPastAppointmentInfoList(Long stakeholderId) {
+        StakeholderType type = stakeholderRepository.findById(stakeholderId).get().getStakeholderType();
+        List<Appointment> appointmentInfoDtoList = new ArrayList<>();
+
+        switch (type) {
+            case BUSINESS_OWNER -> appointmentInfoDtoList = appointmentRepository.findPastAppointmentsByBusinessOwnerId(stakeholderId, LocalDateTime.now());
+            case CUSTOMER -> appointmentInfoDtoList = appointmentRepository.findPastAppointmentsByCustomerId(stakeholderId, LocalDateTime.now());
+        }
+
+        return appointmentInfoDtoList
+                .stream()
+                .map(appointmentInfoDtoBusinessMapper::appointmentToAppointmentInfoDto)
+                .toList();
+
+    }
+
+    public List<Appointment> getActiveAppointmentsByBusiness(Long businessId) {
+        return appointmentRepository.getActiveAppointmentsByBusiness(businessId);
+    }
+
+    public void deleteAppointment(Long appointmentId, Long stakeholderId) throws AuthenticationException {
+        Optional<Stakeholder> stakeholderOptional = stakeholderRepository.findById(stakeholderId);
+        if (stakeholderOptional.isPresent()) {
+            Optional<Appointment> optional = appointmentRepository.findAppointmentByIdAndCustomer_Id(appointmentId, stakeholderId);
+            if (optional.isEmpty()) {
+                optional = appointmentRepository.findAppointmentByIdAndService_Business_Owner_Id(appointmentId, stakeholderId);
+                if (optional.isEmpty()) {
+                    throw new EntityNotFoundException("No appointment was found for the give stakeholder and appointment id.");
+                } else {
+                    softDeleteAppointment(optional.get(), AppointmentStatus.CANCELLED_BY_BUSINESS_OWNER);
+                }
+            } else {
+                softDeleteAppointment(optional.get(), AppointmentStatus.CANCELLED_BY_CUSTOMER);
+            }
+        } else {
+            throw new AuthenticationException();
+        }
+    }
+
+    public void softDeleteAppointment(Appointment appointment, AppointmentStatus appointmentStatus) {
+        appointment.setAppointmentStatus(appointmentStatus);
+        appointmentRepository.save(appointment);
     }
 }
Index: src/main/java/edu/gjoko/schedlr/services/BusinessService.java
===================================================================
--- src/main/java/edu/gjoko/schedlr/services/BusinessService.java	(revision 950fa0d7a6b439770e79c885947e9b7d6058b424)
+++ src/main/java/edu/gjoko/schedlr/services/BusinessService.java	(revision 77205be723c8b2ffd1ee5618a05e1d12b1cee44a)
@@ -2,11 +2,9 @@
 
 import edu.gjoko.schedlr.entity.*;
-import edu.gjoko.schedlr.repositories.BusinessRepository;
-import edu.gjoko.schedlr.repositories.ServiceRepository;
-import edu.gjoko.schedlr.repositories.ServiceTypeRepository;
-import edu.gjoko.schedlr.repositories.StakeholderRepository;
+import edu.gjoko.schedlr.repositories.*;
 import lombok.AllArgsConstructor;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 import java.util.List;
@@ -22,4 +20,5 @@
     private final ServiceTypeRepository serviceTypeRepository;
     private final ServiceRepository serviceRepository;
+    private final StakeholderService stakeholderService;
 
     private final StakeholderRepository stakeholderRepository;
@@ -54,7 +53,7 @@
                 .stream()
                 .forEach(business -> {
-                    stakeholderRepository.save(business.getOwner());
-                    serviceRepository.saveAll(business.getServices());
-                    businessRepository.save(business);
+                    stakeholderService.saveOrUpdateStakeholder(business.getOwner());
+                    saveOrUpdateServices(business.getServices());
+                    saveOrUpdateBusiness(business);
                 });
     }
@@ -66,6 +65,28 @@
     }
 
-    public List<Business> findByBusinessTypeAndActiveStatus(BusinessType businessType) {
-        return businessRepository.findBusinessesByBusinessTypeAndBusinessStatus(businessType, ACTIVE);
+    public List<Business> findByBusinessTypeAndActiveStatus(Long businessTypeId) {
+        return businessRepository.findBusinessesByBusinessStatusAndBusinessType_Id(ACTIVE, businessTypeId);
+    }
+
+
+
+    private void saveOrUpdateBusiness(Business business) {
+        if (business.getId() != null) {
+            var foundBusinessEntity = businessRepository.findById(business.getId());
+            business.setCreated(foundBusinessEntity.get().getCreated());
+        }
+        businessRepository.save(business);
+    }
+
+    private void saveOrUpdateServices(List<edu.gjoko.schedlr.entity.Service> serviceList) {
+        if (!CollectionUtils.isEmpty(serviceList)) {
+            serviceList.forEach( service -> {
+                if (service.getId() != null) {
+                    var found = serviceRepository.findById(service.getId());
+                    service.setCreated(found.get().getCreated());
+                }
+            });
+            serviceRepository.saveAll(serviceList);
+        }
     }
 }
Index: src/main/java/edu/gjoko/schedlr/services/ReviewService.java
===================================================================
--- src/main/java/edu/gjoko/schedlr/services/ReviewService.java	(revision 77205be723c8b2ffd1ee5618a05e1d12b1cee44a)
+++ src/main/java/edu/gjoko/schedlr/services/ReviewService.java	(revision 77205be723c8b2ffd1ee5618a05e1d12b1cee44a)
@@ -0,0 +1,57 @@
+package edu.gjoko.schedlr.services;
+
+import edu.gjoko.schedlr.entity.Appointment;
+import edu.gjoko.schedlr.entity.AppointmentStatus;
+import edu.gjoko.schedlr.entity.Review;
+import edu.gjoko.schedlr.repositories.AppointmentRepository;
+import edu.gjoko.schedlr.repositories.ReviewRepository;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityNotFoundException;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@AllArgsConstructor
+public class ReviewService {
+
+    private final ReviewRepository reviewRepository;
+    private final AppointmentRepository appointmentRepository;
+
+    public void save(Review review, Long customerId) {
+        Optional<Appointment> appointmentOptional = appointmentRepository.findById(review.getAppointment().getId());
+        if (appointmentOptional.isEmpty()) {
+            throw new EntityNotFoundException();
+        }
+        Appointment appointment = appointmentOptional.get();
+        if (appointment.getCustomer().getId().equals(customerId)) {
+            review.setAppointment(appointment);
+            markAppointmentAsReviewed(review.getAppointment());
+            calculateAndUpdateCumulatedRatingForService(appointment.getService(), review.getRating());
+            reviewRepository.save(review);
+        } else {
+            throw new EntityNotFoundException();
+        }
+    }
+
+    public List<Review> getReviewsByServiceId(Long businessId) {
+        return reviewRepository.findAllByAppointment_Service_Id(businessId);
+    }
+
+    public List<Review> getReviewsByCustomerId(Long customerId) {
+        return reviewRepository.findAllByAppointment_Customer_Id(customerId);
+    }
+
+    private void markAppointmentAsReviewed(Appointment appointment) {
+        appointment.setAppointmentStatus(AppointmentStatus.FINISHED_AND_REVIEWED_BY_USER);
+    }
+
+    private void calculateAndUpdateCumulatedRatingForService(edu.gjoko.schedlr.entity.Service service, int rating) {
+        int newReviewsCount = service.getReviewsCount() + 1;
+        float currentRating = service.getRating();
+        float newRating = (currentRating * service.getReviewsCount() + rating) / newReviewsCount;
+        service.setReviewsCount(newReviewsCount);
+        service.setRating(newRating);
+    }
+}
Index: src/main/java/edu/gjoko/schedlr/services/StakeholderService.java
===================================================================
--- src/main/java/edu/gjoko/schedlr/services/StakeholderService.java	(revision 950fa0d7a6b439770e79c885947e9b7d6058b424)
+++ src/main/java/edu/gjoko/schedlr/services/StakeholderService.java	(revision 77205be723c8b2ffd1ee5618a05e1d12b1cee44a)
@@ -6,4 +6,6 @@
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
+
+import java.util.Optional;
 
 @Service
@@ -28,3 +30,15 @@
         return stakeholderRepository.findById(id).get();
     }
+
+    public void saveOrUpdateStakeholder(Stakeholder stakeholder) {
+        if (stakeholder.getId() != null) {
+            var found = stakeholderRepository.findById(stakeholder.getId()).get();
+            found.setFirstName(stakeholder.getFirstName());
+            found.setLastName(stakeholder.getLastName());
+            found.setPhoneNumber(stakeholder.getPhoneNumber());
+            found.setEmail(stakeholder.getEmail());
+            found.setUsername(stakeholder.getUsername());
+            stakeholderRepository.save(found);
+        }
+    }
 }
