//Works as upsert. This partially handles conflicts but still there is a small chance of race condition
        //Using some locks over the transaction (like isolation level serializable) is also possible
        //but may have side effects while reading the data being updating.
        //I think, letting back office throw ex better than affecting the insurance calculation performance as it affects customer experience
        public async Task SaveSurchargeRateAsync(SaveSurchargeRateRequest request)
        {
            var existingRule = await _dbContext
                               .InsuranceProductTypeRules
                               .FirstOrDefaultAsync(rule => rule.Type == InsuranceProductTypeRuleType.AppliesToProduct &&
                                                    rule.ProductTypeId == request.ProductTypeId);

            if (existingRule != null)
            {
                existingRule.InsuranceCost = request.InsuranceCost;
            }
            else
            {
                _dbContext
                .InsuranceProductTypeRules
                .Add(new InsuranceProductTypeRule
                {
                    Type          = InsuranceProductTypeRuleType.AppliesToProduct,
                    InsuranceCost = request.InsuranceCost,
                    ProductTypeId = request.ProductTypeId
                });
            }

            await _dbContext.SaveChangesAsync();
        }
        public async Task <IActionResult> SaveSurchargeRate([FromBody] SaveSurchargeRateRequest saveSurchargeRateRequest)
        {
            await _insuranceCalculatorService.SaveSurchargeRateAsync(saveSurchargeRateRequest);

            return(Ok());
        }