refactor(database): update seed pipeline to use dapper (#277)

This commit is contained in:
Aaron Po
2026-09-05 00:37:14 -04:00
committed by GitHub
parent 78ad32e93a
commit d9411eb00e
43 changed files with 1023 additions and 735 deletions

View File

@@ -29,6 +29,7 @@
<ProjectReference Include="..\..\Features\Features.Users\Features.Users.csproj" />
<ProjectReference Include="..\..\Features\Features.Emails\Features.Emails.csproj" />
<ProjectReference Include="..\..\Features\Features.PhotoUpload\Features.PhotoUpload.csproj" />
<ProjectReference Include="..\..\Features\Features.Locations\Features.Locations.csproj" />
<ProjectReference Include="..\..\Shared\Shared.Contracts\Shared.Contracts.csproj" />
<ProjectReference Include="..\..\Shared\Shared.Application\Shared.Application.csproj" />
</ItemGroup>

View File

@@ -7,6 +7,8 @@ using Features.Emails.DependencyInjection;
using Features.Emails.Services;
using Features.ImageUploads.Commands.UploadPhoto;
using Features.ImageUploads.DependencyInjection;
using Features.Locations.Controllers;
using Features.Locations.DependencyInjection;
using Features.Users.DependencyInjection;
using FluentValidation;
using FluentValidation.AspNetCore;
@@ -26,6 +28,7 @@ internal static class ServiceCollectionExtensions
.AddControllers(options => options.Filters.Add<GlobalExceptionFilter>())
.AddApplicationPart(typeof(BreweryController).Assembly)
.AddApplicationPart(typeof(AuthController).Assembly)
.AddApplicationPart(typeof(CityController).Assembly)
.Services;
public IServiceCollection AddValidationAndMediatR()
@@ -44,6 +47,7 @@ internal static class ServiceCollectionExtensions
cfg.RegisterServicesFromAssembly(typeof(AuthController).Assembly);
cfg.RegisterServicesFromAssembly(typeof(UploadPhotoCommand).Assembly);
cfg.RegisterServicesFromAssembly(typeof(IEmailDispatcher).Assembly);
cfg.RegisterServicesFromAssembly(typeof(CityController).Assembly);
cfg.AddOpenBehavior(typeof(ValidationBehavior<,>));
});
@@ -96,7 +100,8 @@ internal static class ServiceCollectionExtensions
.AddFeaturesBreweries()
.AddFeaturesUsers()
.AddFeaturesEmails()
.AddFeaturesPhotoUpload();
.AddFeaturesPhotoUpload()
.AddFeaturesLocations();
public IServiceCollection AddCoreInfrastructure() =>
services

View File

@@ -1,7 +1,6 @@
using System.Text;
using System.Text.Json;
using Database.Connection;
using Features.Locations.Dtos;
using Features.Locations.Repository;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
@@ -23,11 +22,6 @@ public class BrewerySteps(ScenarioContext scenario) : ApiStepsBase(scenario)
private const string FixtureStateProvinceIsoCode = "FX-TS";
private const string FixtureCityName = "Fixture City";
// GetOrCreateCityIdAsync is not fully race-safe under concurrent callers creating the same
// city (see its remarks); scenarios run in parallel across feature classes, so provisioning
// the shared fixture city is serialized the same way AuthSteps serializes its fixture account.
private static readonly SemaphoreSlim CityProvisioningLock = new(1, 1);
private HttpRequestMessage NewAuthenticatedRequest(HttpMethod method, string url)
{
HttpRequestMessage requestMessage = new(method, url);
@@ -53,24 +47,21 @@ public class BrewerySteps(ScenarioContext scenario) : ApiStepsBase(scenario)
.Services.GetRequiredService<ISqlConnectionFactory>();
LocationRepository repository = new(connectionFactory);
CityLocation fixtureCity = new(
FixtureCityName,
FixtureStateProvinceName,
FixtureStateProvinceIsoCode,
FixtureCountryName,
FixtureCountryIsoCode
);
Guid countryId =
await repository.GetCountryIdAsync(FixtureCountryIsoCode)
?? await repository.CreateCountryAsync(FixtureCountryName, FixtureCountryIsoCode);
await CityProvisioningLock.WaitAsync();
Guid cityId;
try
{
cityId = await repository.GetOrCreateCityIdAsync(fixtureCity);
}
finally
{
CityProvisioningLock.Release();
}
Guid stateProvinceId =
await repository.GetStateProvinceIdAsync(FixtureStateProvinceIsoCode)
?? await repository.CreateStateProvinceAsync(
FixtureStateProvinceName,
FixtureStateProvinceIsoCode,
countryId
);
Guid cityId =
await repository.GetCityIdAsync(FixtureCityName, FixtureStateProvinceIsoCode)
?? await repository.CreateCityAsync(FixtureCityName, stateProvinceId);
Scenario[CityIdKey] = cityId;
}