private async Task AddTenantToShardManagerAsync(TenantInitializeDetails details, string shardMapName)
        {
            var shardMapId = (await Smdb.ShardMapsGlobal.Where(z => z.Name == shardMapName).FirstAsync()).ShardMapId;

            var shardId         = Guid.NewGuid();
            var shardVersion    = Guid.NewGuid();
            var lastOperationId = Guid.NewGuid();

            var finder = new MyDummyTenantFinder(details.DatabaseName, details.TenantId);

            using (var rdb = new TraffkTenantModelDbContext(RdbOptions, finder, new ConfigStringFormatter(finder)
            {
            }))
            {
                rdb.ShardMapsLocal.Add(new ShardMapsLocal {
                    ShardMapId      = shardMapId,
                    Name            = shardMapName,
                    MapType         = 1,
                    KeyType         = 1,
                    LastOperationId = lastOperationId
                });
                rdb.ShardsLocal.Add(new ShardsLocal {
                    ShardId         = shardId,
                    Version         = shardVersion,
                    ShardMapId      = shardMapId,
                    Protocol        = 0,
                    ServerName      = details.DatabaseServer,
                    Port            = 0,
                    DatabaseName    = details.DatabaseName,
                    Status          = 1,
                    LastOperationId = lastOperationId
                });
                await rdb.SaveChangesAsync();
            }

            Smdb.ShardsGlobal.Add(new ShardsGlobal {
                ShardId      = shardId,
                Readable     = true,
                Version      = shardVersion,
                ShardMapId   = shardMapId,
                Protocol     = 0,
                ServerName   = ConfigOptions.Value.FullyQualifiedServerName,
                Port         = 0,
                DatabaseName = details.DatabaseName,
                Status       = 1
            });
            await Smdb.SaveChangesAsync();
        }
        async Task ITenantManagementJobs.InitializeNewTenantAsync(TenantInitializeDetails details)
        {
            var finder = new MyDummyTenantFinder(details.DatabaseName, details.TenantId);

            using (var rdb = new TraffkTenantModelDbContext(RdbOptions, finder, new ConfigStringFormatter(finder)
            {
            }))
            {
                try
                {
                    rdb.Database.OpenConnection();
                }
                catch (Exception sex)
                {
                    throw new Exception("Database has not been created yet", sex);
                }
                using (var trans = await rdb.Database.BeginTransactionAsync())
                {
                    var t = await rdb.Tenants.FindAsync(details.TenantId);

                    if (t == null)
                    {
                        t = new Tenant
                        {
                            TenantId   = details.TenantId,
                            TenantName = details.TenantName,
                            TenantType = Tenant.TenantTypes.Normal,
                        };
                        rdb.Tenants.Add(t);
                        rdb.Apps.Add(new App
                        {
                            Tenant  = t,
                            AppType = AppTypes.Portal,
                            AppName = AppTypes.Portal.ToString(),
                        });
                        await rdb.SaveChangesAsync();

                        var r = new ApplicationRole
                        {
                            Tenant         = t,
                            Name           = "Bootstrap",
                            NormalizedName = "bootstrap",
                        };
                        rdb.Roles.Add(r);
                        var u = new ApplicationUser
                        {
                            Tenant             = t,
                            Email              = details.AdminUsername,
                            NormalizedEmail    = details.AdminUsername.ToUpper(),
                            NormalizedUserName = details.AdminUsername.ToUpper(),
                        };
                        rdb.Users.Add(u);
                        await rdb.SaveChangesAsync();

                        u.PasswordHash = PasswordHasher.HashPassword(u, details.AdminPassword);
                        rdb.UserRoles.Add(new ApplicationUserRole
                        {
                            UserId = u.Id,
                            RoleId = r.Id,
                        });
                        foreach (var p in new[] {
                            PermissionNames.ManageJobs,
                            PermissionNames.ManageUsers,
                            PermissionNames.ManageRoles,
                            PermissionNames.ManageTenants,
                            PermissionNames.CustomerRelationshipData,
                            PermissionNames.DirectMessaging,
                            PermissionNames.ReleaseLog,
                        })
                        {
                            rdb.RoleClaims.Add(new RoleClaim
                            {
                                RoleId     = r.Id,
                                ClaimType  = PermissionHelpers.CreateClaimType(p),
                                ClaimValue = new PermissionClaimValue(true).ToJson()
                            });
                        }
                    }
                    await rdb.SaveChangesAsync();

                    trans.Commit();
                }
            }
        }