using Bit.Core.Utilities;
using Bit.Infrastructure.EntityFramework.Repositories;
using LinqToDB.EntityFrameworkCore;
namespace Bit.Seeder.Recipes;
public class GroupsRecipe(DatabaseContext db)
{
///
/// Adds groups to an organization and creates relationships between users and groups.
///
/// The ID of the organization to add groups to.
/// The number of groups to add.
/// The IDs of the users to create relationships with.
/// The maximum number of users to create relationships with.
public List AddToOrganization(Guid organizationId, int groups, List organizationUserIds, int maxUsersWithRelationships = 1000)
{
var groupList = CreateAndSaveGroups(organizationId, groups);
if (groupList.Any())
{
CreateAndSaveGroupUserRelationships(groupList, organizationUserIds, maxUsersWithRelationships);
}
return groupList.Select(g => g.Id).ToList();
}
private List CreateAndSaveGroups(Guid organizationId, int count)
{
var groupList = new List();
for (var i = 0; i < count; i++)
{
groupList.Add(new Core.AdminConsole.Entities.Group
{
Id = CoreHelpers.GenerateComb(),
OrganizationId = organizationId,
Name = $"Group {i + 1}"
});
}
if (groupList.Any())
{
db.BulkCopy(groupList);
}
return groupList;
}
private void CreateAndSaveGroupUserRelationships(
List groups,
List organizationUserIds,
int maxUsersWithRelationships)
{
if (!organizationUserIds.Any() || maxUsersWithRelationships <= 0)
{
return;
}
var groupUsers = BuildGroupUserRelationships(groups, organizationUserIds, maxUsersWithRelationships);
if (groupUsers.Any())
{
db.BulkCopy(groupUsers);
}
}
///
/// Creates user-to-group relationships with distributed assignment patterns for realistic test data.
/// Each user is assigned to one group, distributed evenly across available groups.
///
private List BuildGroupUserRelationships(
List groups,
List organizationUserIds,
int maxUsersWithRelationships)
{
var maxRelationships = Math.Min(organizationUserIds.Count, maxUsersWithRelationships);
var groupUsers = new List();
for (var i = 0; i < maxRelationships; i++)
{
var orgUserId = organizationUserIds[i];
var groupIndex = i % groups.Count; // Round-robin distribution across groups
groupUsers.Add(new Core.AdminConsole.Entities.GroupUser
{
GroupId = groups[groupIndex].Id,
OrganizationUserId = orgUserId
});
}
return groupUsers;
}
}