Beispiel #1
0
        public async Task <ActionResult <UserInstitution> > PostUserInstitution(UserInstitution userInstitution)
        {
            _context.UserInstitutions.Add(userInstitution);
            await _context.SaveChangesAsync();

            return(CreatedAtAction("GetUserInstitution", new { id = userInstitution.Id }, userInstitution));
        }
Beispiel #2
0
        public async Task <IActionResult> PutUserInstitution(Guid id, UserInstitution userInstitution)
        {
            if (id != userInstitution.Id)
            {
                return(BadRequest());
            }

            _context.Entry(userInstitution).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!UserInstitutionExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(NoContent());
        }
        /// <summary>
        /// Scrap user by using browser (usually Chrome browser).
        /// Slow algorithm but safe method
        /// </summary>
        /// <param name="profileLink">Full link to user profile starts with 'https://m.facebook.com/'</param>
        /// <param name="isInFriendList">If user has in your friend list</param>
        /// <param name="callback">Callback function after completing this method</param>
        public void ScrapUserBrowser(string profileLink, bool isInFriendList = false, Action callback = null)
        {
            _startupWindow = _driver.CurrentWindowHandle;
            OpenNewTab(profileLink);
            WaitForReady(By.Id("timelineContextList"));
            _htmlDoc.LoadHtml(_driver.PageSource);

            var    actionBarButtonNodes = _htmlDoc.DocumentNode.SelectNodes("//*[@data-sigil='hq-profile-logging-action-bar-button flyout-causal']");
            string jsonData;

            if (actionBarButtonNodes.Count >= 2)
            {
                jsonData = _htmlDoc.DocumentNode.SelectNodes("//*[@data-sigil='hq-profile-logging-action-bar-button flyout-causal']")[1].Attributes["data-store"].DeEntitizeValue;
            }
            else
            {
                jsonData = _htmlDoc.DocumentNode.SelectNodes("//*[@data-sigil='hq-profile-logging-action-bar-button flyout-causal']")[0].Attributes["data-store"].DeEntitizeValue;
            }

            string profileId    = JObject.Parse(jsonData)["hq-profile-logging"]["profile_id"].ToString();
            string sessionToken = JObject.Parse(jsonData)["hq-profile-logging"]["profile_session_token"].ToString();

            using (var db = new ApplicationDbContext())
            {
                if (UserExistsInDb((i => i.Id == profileId), db) || profileId == "100004966276119")
                {
                    _driver.Close();
                    _driver.SwitchTo().Window(_startupWindow);
                    callback?.Invoke();
                    return;
                }

                var    membershipNode = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='profile_intro_card']/.//span[contains(text(), 'На Facebook с')]");
                var    bioNode        = _htmlDoc.GetElementbyId("bio");
                string userFullName   = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='cover-name-root']/h3").InnerText;
                string username       = profileLink.Split('/').Last();
                string headerImgSrc   = "null";
                string profileImgSrc  = "null";
                string profileBio     = "null";

                if (IsElementPresent(By.XPath("//div[@data-sigil='cover-photo']/a/i")))
                {
                    headerImgSrc = _driver.FindElement(By.XPath("//div[@data-sigil='cover-photo']/a/i")).GetCssValue("background").Split("url(")[1].Split("\"")[1];
                }

                if (IsElementPresent(By.XPath("//i[@class='img profpic']")))
                {
                    profileImgSrc = _driver.FindElement(By.XPath("//i[@class='img profpic']")).GetCssValue("background").Split("url(")[1].Split("\"")[1];
                }

                if (bioNode != null)
                {
                    profileBio = bioNode.InnerText;
                }

                var user = new User()
                {
                    Id              = profileId,
                    Username        = username,
                    ProfilePhotoSrc = profileImgSrc,
                    HeaderPhotoSrc  = headerImgSrc,
                    Bio             = profileBio,
                    IsMyFriend      = isInFriendList
                };
                user.ParseFLName(userFullName);

                if (membershipNode != null)
                {
                    user.MemberSince = DateTime.Parse(membershipNode.InnerText.Split(" с ")[1]);
                }

                string aboutUrl = "about";

                if (profileLink.Contains("profile.php"))
                {
                    aboutUrl    = $"?v=info&Ist={sessionToken}&id={sessionToken.Split(':')[1]}";
                    _driver.Url = $"https://m.facebook.com/profile.php{aboutUrl}";
                }
                else
                {
                    _driver.Navigate().GoToUrl($"{profileLink.Trim()}/{aboutUrl}");
                }

                _htmlDoc.LoadHtml(_driver.PageSource);

                var contactInfo  = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='contact-info']/div");
                var basicInfo    = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='basic-info']/div");
                var educations   = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='education']/div");
                var works        = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='work']/div");
                var livedCities  = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='living']/div");
                var skills       = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='skills']/div");
                var quote        = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='quote']/div");
                var relationship = _htmlDoc.DocumentNode.SelectSingleNode("//*[@id='relationship']/div");

                if (basicInfo != null)
                {
                    foreach (var item in basicInfo.ChildNodes)
                    {
                        if (item.Attributes["title"].Value == "Дата рождения")
                        {
                            string birthdayNode = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                            if (DateTime.TryParse(birthdayNode, out DateTime birthday))
                            {
                                user.Birthday = birthday;
                            }
                        }

                        if (item.Attributes["title"].Value == "Пол")
                        {
                            user.Gender = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "Языки")
                        {
                            user.Languages = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "Религиозные взгляды")
                        {
                            user.ReligiousView = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }
                    }
                }

                if (contactInfo != null)
                {
                    var contactNumbersList = new List <string>();
                    var webSitesList       = new List <string>();
                    foreach (var item in contactInfo.ChildNodes)
                    {
                        if (item.Attributes["title"].Value == "Мобильный")
                        {
                            contactNumbersList.Add(item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText);
                        }

                        if (item.Attributes["title"].Value == "OK")
                        {
                            user.OK = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "Twitter")
                        {
                            user.Twitter = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "VK")
                        {
                            user.VK = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "Instagram")
                        {
                            user.Instagram = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "YouTube")
                        {
                            user.YouTube = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "LinkedIn")
                        {
                            user.LinkedIn = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "GitHub")
                        {
                            user.GitHub = item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText;
                        }

                        if (item.Attributes["title"].Value == "Веб-сайты")
                        {
                            webSitesList.Add(item.SelectSingleNode(".//div[@class='lr']/div[contains(@class, ' r')]").InnerText);
                        }
                    }
                    user.ContactNumbers = string.Join(',', contactNumbersList);
                    user.WebSites       = string.Join(',', webSitesList);
                }

                if (educations != null)
                {
                    var institutions = new HashSet <UserInstitution>(new UserInstitutionComparer());
                    foreach (var item in educations.ChildNodes)
                    {
                        var    node            = item.SelectSingleNode(".//div/span/a");
                        string link            = node.Attributes["href"].Value;
                        string name            = node.InnerText;
                        string institutionType = item.SelectNodes(".//div/span")[1].InnerText;

                        var institution = new Institution()
                        {
                            Name = name,
                            Link = link
                        };

                        if (institutionType != "Средняя школа")
                        {
                            institution.IsHigherEducation = true;
                        }

                        if (db.Institutions.Where(i => i.Link == institution.Link).FirstOrDefault() != null)
                        {
                            institution = db.Institutions.Where(i => i.Link == institution.Link).FirstOrDefault();
                        }
                        else
                        {
                            institution = db.Institutions.Add(institution).Entity;
                        }

                        var userInstitution = new UserInstitution()
                        {
                            Institution = institution
                        };
                        institutions.Add(userInstitution);
                    }
                    user.Institutions.AddRange(institutions);
                }

                if (works != null)
                {
                    foreach (var item in works.ChildNodes)
                    {
                        var    node          = item.SelectSingleNode(".//span/a");
                        string link          = node.Attributes["href"].Value;
                        string name          = node.InnerText;
                        string position      = "null";
                        string workingPeriod = "null";

                        var company = new Company()
                        {
                            Name = name,
                            Link = link
                        };

                        if (db.Companies.Where(i => i.Link == company.Link).FirstOrDefault() != null)
                        {
                            company = db.Companies.Where(i => i.Link == company.Link).FirstOrDefault();
                        }
                        else
                        {
                            company = db.Companies.Add(company).Entity;
                        }

                        var work = new Employee()
                        {
                            Company = company
                        };

                        if (item.SelectNodes(".//span").Count > 2)
                        {
                            position      = item.SelectNodes(".//span")[1].InnerText;
                            workingPeriod = item.SelectNodes(".//span")[2].InnerText;
                            work.Position = position;

                            if (workingPeriod.Contains("по настоящее время"))
                            {
                                work.IsCurrentlyWorking = true;
                                string startDateString = workingPeriod.Substring(3, (workingPeriod.IndexOf("по ") - 3));

                                if (DateTime.TryParse(startDateString, out DateTime startWorkDate))
                                {
                                    work.StartWorkDate = startWorkDate;
                                }
                            }
                            else if (workingPeriod == "Я работаю здесь в настоящее время")
                            {
                                work.IsCurrentlyWorking = true;
                            }
                            else
                            {
                                string[] dates = null;
                                if (workingPeriod.Contains('-'))
                                {
                                    dates = workingPeriod.Split('-');
                                }
                                else if (workingPeriod.Contains('—'))
                                {
                                    dates = workingPeriod.Split('—');
                                }

                                if (dates != null && dates.Length >= 2)
                                {
                                    if (DateTime.TryParse(dates[0], out DateTime startWorkDate))
                                    {
                                        work.StartWorkDate = startWorkDate;
                                    }
                                    if (DateTime.TryParse(dates[1], out DateTime endWorkDate))
                                    {
                                        work.EndWorkDate = endWorkDate;
                                    }
                                }
                            }
                        }

                        user.Works.Add(work);
                    }
                }

                if (livedCities != null)
                {
                    var livedCitiesList = new List <string>();
                    foreach (var item in livedCities.ChildNodes)
                    {
                        var    nodes      = item.SelectNodes(".//header/h4");
                        string cityName   = nodes[0].InnerText;
                        string livingType = nodes[1].InnerText;

                        if (livingType == "Родной город")
                        {
                            user.Hometown = cityName;
                        }
                        else
                        {
                            livedCitiesList.Add(cityName);
                        }
                    }
                    user.LivedCities = string.Join(" * ", livedCitiesList);
                }

                if (skills != null)
                {
                    user.Skills = skills.InnerText;
                }

                if (quote != null)
                {
                    user.Quote = quote.InnerText;
                }

                if (relationship != null)
                {
                    user.MaritalStatus = relationship.InnerText;
                }

                db.Users.Add(user);
                db.SaveChanges();
                Console.Write(user);
            }

            _driver.Close();
            _driver.SwitchTo().Window(_startupWindow);
            callback?.Invoke();
        }
        /// <summary>
        /// Scrap user by using browser (usually Chrome browser).
        /// Fast algorithm but safeless method
        /// </summary>
        /// <param name="profileLink">Full link to user profile starts with 'https://m.facebook.com/'</param>
        /// <param name="isInFriendList">If user has in your friend list</param>
        /// <param name="callback">Callback function, will invoke after completing this method</param>
        public void ScrapUserHidelessBrowser(string profileLink, bool isInFriendList = false, Action callback = null)
        {
            var aboutPage = _browser.NavigateToPage(new Uri($"{profileLink}/about/"));
            var document  = _parser.ParseDocument(aboutPage.Content);
            var profileId = document.Body.QuerySelectorAll("a").Where(i => i.GetAttribute("href").Contains("owner_id")).First().GetAttribute("href").Split("owner_id=")[1];

            using (var db = new ApplicationDbContext())
            {
                if (UserExistsInDb((i => i.Id == profileId), db) || profileId == "100004966276119")
                {
                    return;
                }

                string username      = profileLink.Split('/').Last();
                string profileBio    = document.Body.QuerySelector("div.co.cp.cq.cr")?.TextContent;
                string userFullName  = document.Body.QuerySelector("span > strong")?.TextContent;
                string headerImgSrc  = document.Body.QuerySelector("#profile_cover_photo_container > a > img")?.GetAttribute("src");
                string profileImgSrc = document.Body.QuerySelector("img.cb.r")?.GetAttribute("src");

                var user = new User()
                {
                    Id              = profileId,
                    Username        = username,
                    ProfilePhotoSrc = profileImgSrc,
                    HeaderPhotoSrc  = headerImgSrc,
                    Bio             = profileBio,
                    IsMyFriend      = isInFriendList
                };
                user.ParseFLName(userFullName);

                var basicInfo    = document.Body.QuerySelector("#basic-info > div > div:nth-child(2)");
                var contactInfo  = document.Body.QuerySelector("#contact-info > div > div:nth-child(2)");
                var educations   = document.Body.QuerySelector("#education > div > div:nth-child(2)");
                var works        = document.Body.QuerySelector("#work > div > div:nth-child(2)");
                var livedCities  = document.Body.QuerySelector("#living > div > div:nth-child(2)");
                var skills       = document.Body.QuerySelector("#skills > div > div:nth-child(2)");
                var quote        = document.Body.QuerySelector("#quote > div > div:nth-child(2)");
                var relationship = document.Body.QuerySelector("#relationship > div > div:nth-child(2)");

                var contactNumbersList = new List <string>();
                var webSitesList       = new List <string>();
                var livedCitiesList    = new List <string>();
                var institutions       = new HashSet <UserInstitution>(new UserInstitutionComparer());

                if (basicInfo != null)
                {
                    foreach (var item in basicInfo.Children)
                    {
                        if (item.Attributes["title"].Value == "Дата рождения")
                        {
                            string birthdayNode = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                            if (DateTime.TryParse(birthdayNode, out DateTime birthday))
                            {
                                user.Birthday = birthday;
                            }
                        }

                        if (item.Attributes["title"].Value == "Пол")
                        {
                            user.Gender = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "Языки")
                        {
                            user.Languages = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "Религиозные взгляды")
                        {
                            user.ReligiousView = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }
                    }
                }

                if (contactInfo != null)
                {
                    foreach (var item in contactInfo.Children)
                    {
                        if (item.Attributes["title"].Value == "Мобильный")
                        {
                            contactNumbersList.Add(item.QuerySelector("td[valign='top']:nth-child(2)").TextContent);
                        }

                        if (item.Attributes["title"].Value == "OK")
                        {
                            user.OK = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "Twitter")
                        {
                            user.Twitter = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "VK")
                        {
                            user.VK = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "Instagram")
                        {
                            user.Instagram = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "YouTube")
                        {
                            user.YouTube = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "LinkedIn")
                        {
                            user.LinkedIn = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "GitHub")
                        {
                            user.GitHub = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        }

                        if (item.Attributes["title"].Value == "Веб-сайты")
                        {
                            webSitesList.Add(item.QuerySelector("td[valign='top']:nth-child(2)").TextContent);
                        }
                    }
                }

                if (educations != null)
                {
                    foreach (var item in educations.Children)
                    {
                        var    nodes           = item.QuerySelectorAll("div > span");
                        var    eduNode         = nodes.Select(i => i.QuerySelector("a")).First();
                        string link            = eduNode.Attributes["href"].Value;
                        string name            = eduNode.TextContent;
                        string institutionType = nodes[1].TextContent;

                        var institution = new Institution()
                        {
                            Name = name,
                            Link = link
                        };

                        if (institutionType != "Средняя школа")
                        {
                            institution.IsHigherEducation = true;
                        }

                        if (db.Institutions.Where(i => i.Link == institution.Link).FirstOrDefault() != null)
                        {
                            institution = db.Institutions.Where(i => i.Link == institution.Link).FirstOrDefault();
                        }
                        else
                        {
                            institution = db.Institutions.Add(institution).Entity;
                        }

                        var userInstitution = new UserInstitution()
                        {
                            Institution = institution
                        };
                        institutions.Add(userInstitution);
                    }
                }

                if (works != null)
                {
                    foreach (var item in works.Children)
                    {
                        var    node          = item.QuerySelector("span > a");
                        string link          = node.Attributes["href"].Value;
                        string name          = node.TextContent;
                        string position      = "null";
                        string workingPeriod = "null";

                        var company = new Company()
                        {
                            Name = name,
                            Link = link
                        };

                        if (db.Companies.Where(i => i.Link == company.Link).FirstOrDefault() != null)
                        {
                            company = db.Companies.Where(i => i.Link == company.Link).FirstOrDefault();
                        }
                        else
                        {
                            company = db.Companies.Add(company).Entity;
                        }

                        var work = new Employee()
                        {
                            Company = company
                        };

                        if (item.QuerySelectorAll("span").Length > 2)
                        {
                            position      = item.QuerySelectorAll("span")[1]?.TextContent;
                            workingPeriod = item.QuerySelectorAll("span")[2]?.TextContent;
                            work.Position = position;

                            if (workingPeriod.Contains("по настоящее время"))
                            {
                                work.IsCurrentlyWorking = true;
                                string startDateString = workingPeriod.Substring(3, (workingPeriod.IndexOf("по ") - 3));

                                if (DateTime.TryParse(startDateString, out DateTime startWorkDate))
                                {
                                    work.StartWorkDate = startWorkDate;
                                }
                            }
                            else if (workingPeriod == "Я работаю здесь в настоящее время")
                            {
                                work.IsCurrentlyWorking = true;
                            }
                            else
                            {
                                string[] dates = null;
                                if (workingPeriod.Contains('-'))
                                {
                                    dates = workingPeriod.Split('-');
                                }
                                else if (workingPeriod.Contains('—'))
                                {
                                    dates = workingPeriod.Split('—');
                                }

                                if (dates != null && dates.Length >= 2)
                                {
                                    if (DateTime.TryParse(dates[0], out DateTime startWorkDate))
                                    {
                                        work.StartWorkDate = startWorkDate;
                                    }
                                    if (DateTime.TryParse(dates[1], out DateTime endWorkDate))
                                    {
                                        work.EndWorkDate = endWorkDate;
                                    }
                                }
                            }
                        }

                        user.Works.Add(work);
                    }
                }

                if (livedCities != null)
                {
                    foreach (var item in livedCities.Children)
                    {
                        string cityName   = item.QuerySelector("td[valign='top']:nth-child(2)").TextContent;
                        string livingType = item.QuerySelector("td[valign='top']:nth-child(1)").TextContent;

                        if (livingType == "Родной город")
                        {
                            user.Hometown = cityName;
                        }
                        else
                        {
                            livedCitiesList.Add(cityName);
                        }
                    }
                }

                user.Skills        = skills?.TextContent;
                user.Quote         = quote?.TextContent;
                user.MaritalStatus = relationship?.TextContent;

                if (contactNumbersList.Count > 0)
                {
                    user.ContactNumbers = string.Join(',', contactNumbersList);
                }

                if (webSitesList.Count > 0)
                {
                    user.WebSites = string.Join(',', webSitesList);
                }

                if (livedCitiesList.Count > 0)
                {
                    user.LivedCities = string.Join(" * ", livedCitiesList);
                }

                if (institutions.Count > 0)
                {
                    user.Institutions.AddRange(institutions);
                }

                db.Users.Add(user);
                db.SaveChanges();
                Console.Write(user);
            }

            callback?.Invoke();
        }
        private async Task GenerateTestData()
        {
            var overallStopwatch = Stopwatch.StartNew();
            var userId           = Guid.NewGuid();
            var now    = DateTime.UtcNow;
            var random = new Random();

            var userStopwatch = Stopwatch.StartNew();
            var user          = new User
            {
                Id = userId.ToString(),
                CreatedDateTimeUTC = now,
                FiservUser         = new FiservUser
                {
                    CashEdgeId          = "123456",
                    CreatedDateTimeUTC  = now,
                    ModifiedDateTimeUTC = now,
                    Password            = Guid.NewGuid().ToString(),
                    Username            = Guid.NewGuid().ToString()
                },
                PartitionKey = userId.ToString(),
            };

            await _userPartitionRepository.AddItemAsync(user);

            userStopwatch.Stop();
            _logger.LogInformation("Added user in {userElapsed}ms", userStopwatch.ElapsedMilliseconds);


            var numberOfUserInstitutions = random.Next(1, 5);

            for (int i = 0; i < numberOfUserInstitutions; i++)
            {
                var userInstitutionStopwatch = Stopwatch.StartNew();
                var userInstitutionId        = Guid.NewGuid();
                var userInstitution          = new UserInstitution
                {
                    Active             = true,
                    CreatedDateTimeUTC = now,
                    CredentialUpdateRequestDateTimeUTC = now,
                    FinancialInstitutionLoginAccountId = 123,
                    HarvestAddId          = "ABC123",
                    HasInvalidCredentials = true,
                    HasMfa      = false,
                    Institution = new InstitutionSlim
                    {
                        Name = "Chase"
                    },
                    Id = userInstitutionId.ToString(),
                    LoginParameterHash  = "hash",
                    ModifiedDateTimeUTC = now,
                    RunId        = 1234567890,
                    PartitionKey = userId.ToString()
                };

                await _userPartitionRepository.AddItemAsync(userInstitution);

                userInstitutionStopwatch.Stop();
                _logger.LogInformation("Added user institutions in {elapsed}ms", userInstitutionStopwatch.ElapsedMilliseconds);

                var numberOfFInancialAccounts = random.Next(1, 8);
                for (int j = 0; j < numberOfFInancialAccounts; j++)
                {
                    var financialAccountStopwatch = Stopwatch.StartNew();
                    var financialAccountId        = Guid.NewGuid();
                    var financialAccount1         = new FinancialAccount
                    {
                        AggregatorAccountId         = "1",
                        AggregatorLastUpdateAttempt = now,
                        AggregatorLastUpdateSuccess = now,
                        CreatedDateTimeUTC          = now,
                        ModifiedDateTimeUTC         = now,
                        Type         = AcctType.CCA,
                        ExtendedType = ExtAcctType.CCA,
                        Owners       = new List <Owner>
                        {
                            new Owner
                            {
                                CreatedDateTimeUTC  = now,
                                ModifiedDateTimeUTC = now,
                                Name = "Lewis Hamilton"
                            },
                            new Owner
                            {
                                CreatedDateTimeUTC  = now,
                                ModifiedDateTimeUTC = now,
                                Name = "Lando Norris"
                            }
                        },
                        Id           = financialAccountId.ToString(),
                        IsActive     = true,
                        Name         = "Credit Card",
                        Number       = "123",
                        PartitionKey = userInstitutionId.ToString()
                    };

                    await _userInstitutionPartitionRepository.AddItemAsync(financialAccount1);

                    financialAccountStopwatch.Stop();
                    _logger.LogInformation("Add financial account in {elapsed}ms", financialAccountStopwatch.ElapsedMilliseconds);

                    var balanceStopwatch = Stopwatch.StartNew();
                    var balances         = new List <Balance>
                    {
                        new Balance
                        {
                            Amount = new Amount
                            {
                                Currency = CurCodeType.USD,
                                Value    = 3.50m
                            },
                            CreatedDateTimeUTC  = now,
                            ModifiedDateTimeUTC = now,
                            PartitionKey        = financialAccountId.ToString(),
                            Type = BalType.Avail
                        },
                        new Balance
                        {
                            Amount = new Amount
                            {
                                Currency = CurCodeType.USD,
                                Value    = 3.50m
                            },
                            CreatedDateTimeUTC  = now,
                            ModifiedDateTimeUTC = now,
                            PartitionKey        = financialAccountId.ToString(),
                            Type = BalType.Current
                        }
                    };
                    balanceStopwatch.Stop();

                    await _financialAccountPartitionRepository.AddItemsAsync(balances).ContinueWith(act =>
                    {
                        _logger.LogInformation("Added 2 balances in {elapsed}ms", balanceStopwatch.ElapsedMilliseconds);
                    });

                    var currentBalances = balances.Select(b => new CurrentBalance
                    {
                        Amount = b.Amount,
                        Type   = b.Type
                    })
                                          .ToList();

                    userInstitution.FinancialAccounts.Add(new FinancialAccountSlim
                    {
                        AcountNumber       = financialAccount1.Number,
                        CreatedDateTimeUTC = now,
                        CurrentBalances    = currentBalances
                    });

                    await _userInstitutionPartitionRepository.UpdateItemAsync(userInstitution);

                    var numberOfTransactions     = random.Next(1, 8000);
                    var transactions             = new List <Transaction>();
                    var transactionStopwatch     = Stopwatch.StartNew();
                    var userTransactions         = new List <UserTransaction>();
                    var userTransactionStopwatch = Stopwatch.StartNew();
                    for (int k = 0; k < numberOfTransactions; k++)
                    {
                        var transaction = new Transaction
                        {
                            AggregatorTransactionId = 1,
                            Amount = new Amount
                            {
                                Currency = CurCodeType.USD,
                                Value    = 3.50m
                            },
                            Category           = "Test",
                            CreatedDateTimeUTC = now,
                            PartitionKey       = financialAccountId.ToString(),
                            Memo = "memo",
                            ModifiedDateTimeUTC = now,
                            PostedDate          = now,
                            Subcategory         = "Test",
                            Type = TransactionType.DEBIT
                        };

                        var doc = JsonSerializer.Serialize(transaction);

                        transactions.Add(transaction);

                        var userTransaction = new UserTransaction
                        {
                            AggregatorTransactionId = transaction.AggregatorTransactionId,
                            Amount             = transaction.Amount,
                            Category           = transaction.Category,
                            CreatedDateTimeUTC = transaction.CreatedDateTimeUTC,
                            FinancialAccountId = financialAccountId,
                            Id   = transaction.Id,
                            Memo = transaction.Memo,
                            ModifiedDateTimeUTC = transaction.ModifiedDateTimeUTC,
                            PartitionKey        = userId.ToString(),
                            PostedDate          = transaction.PostedDate,
                            Subcategory         = transaction.Subcategory,

                            Type = transaction.Type,
                        };

                        userTransactions.Add(userTransaction);
                    }

                    await _userPartitionRepository.AddItemsAsync(userTransactions).ContinueWith(act =>
                    {
                        userTransactionStopwatch.Stop();
                        _logger.LogInformation("Added {count} user transactions in {elapsed}ms", numberOfTransactions, userTransactionStopwatch.ElapsedMilliseconds);
                    });

                    await _financialAccountPartitionRepository.AddItemsAsync(transactions).ContinueWith(act =>
                    {
                        userTransactionStopwatch.Stop();
                        _logger.LogInformation("Add {count} transactions in {elapsed}ms", numberOfTransactions, transactionStopwatch.ElapsedMilliseconds);
                    });
                }
            }
            overallStopwatch.Stop();

            _logger.LogInformation("Completed add user {userId} in {overall}ms", userId, overallStopwatch.ElapsedMilliseconds);
        }