using AutoMapper;
using Bit.Core.Entities;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Seeder.Options;
using Bit.Seeder.Pipeline;
using Bit.Seeder.Services;
using Microsoft.AspNetCore.Identity;
namespace Bit.Seeder.Recipes;
///
/// Seeds an organization from an embedded preset or programmatic options.
///
///
/// Thin facade over the internal Pipeline architecture (RecipeOrchestrator).
/// All orchestration logic is encapsulated within the Pipeline, keeping this Recipe simple.
/// The CLI remains "dumb" - it creates this recipe and calls Seed().
///
public class OrganizationRecipe(
DatabaseContext db,
IMapper mapper,
IPasswordHasher passwordHasher,
IManglerService manglerService)
{
private readonly RecipeOrchestrator _orchestrator = new(db, mapper);
///
/// Seeds an organization from an embedded preset.
///
/// Name of the embedded preset (e.g., "dunder-mifflin-full")
/// Optional password for all seeded accounts
/// The organization ID and summary statistics.
public SeedResult Seed(string presetName, string? password = null)
{
var result = _orchestrator.Execute(presetName, passwordHasher, manglerService, password);
return new SeedResult(
result.OrganizationId,
result.OwnerEmail,
result.UsersCount,
result.GroupsCount,
result.CollectionsCount,
result.CiphersCount);
}
///
/// Seeds an organization from programmatic options (CLI arguments).
///
/// Options specifying what to seed.
/// The organization ID and summary statistics.
public SeedResult Seed(OrganizationVaultOptions options)
{
var result = _orchestrator.Execute(options, passwordHasher, manglerService);
return new SeedResult(
result.OrganizationId,
result.OwnerEmail,
result.UsersCount,
result.GroupsCount,
result.CollectionsCount,
result.CiphersCount);
}
///
/// Lists all available embedded presets and fixtures.
///
/// Available presets grouped by category.
public static AvailableSeeds ListAvailable()
{
var internalResult = RecipeOrchestrator.ListAvailable();
return new AvailableSeeds(internalResult.Presets, internalResult.Fixtures);
}
}
///
/// Result of seeding operation with summary statistics.
///
public record SeedResult(
Guid OrganizationId,
string? OwnerEmail,
int UsersCount,
int GroupsCount,
int CollectionsCount,
int CiphersCount);
///
/// Available presets and fixtures grouped by category.
///
public record AvailableSeeds(
IReadOnlyList Presets,
IReadOnlyDictionary> Fixtures);