Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
# context since the per-section split (nobodies-collective/Humans#858).
run: |
dotnet tool install --global dotnet-ef --version 10.0.*
for ctx in HumansDbContext SystemSettingsDbContext; do
for ctx in HumansDbContext SystemSettingsDbContext ContainersDbContext; do
dotnet ef migrations has-pending-model-changes \
--context "$ctx" \
--project src/Humans.Infrastructure \
Expand Down Expand Up @@ -174,7 +174,7 @@ jobs:
- name: Apply per-section baselines from scratch
run: |
set -euo pipefail
for ctx in SystemSettingsDbContext; do
for ctx in SystemSettingsDbContext ContainersDbContext; do
db="humans_$(echo "$ctx" | tr '[:upper:]' '[:lower:]')"
docker exec "${{ steps.pg.outputs.container }}" \
psql -U humans -d postgres -c "CREATE DATABASE $db"
Expand All @@ -193,7 +193,7 @@ jobs:
# Belt-and-suspenders: Layer 1 already runs this in the build job,
# but re-checking after a real apply guards against any state the
# apply step might have observed differently from a static check.
for ctx in HumansDbContext SystemSettingsDbContext; do
for ctx in HumansDbContext SystemSettingsDbContext ContainersDbContext; do
dotnet ef migrations has-pending-model-changes \
--context "$ctx" \
--project src/Humans.Infrastructure \
Expand Down
33 changes: 33 additions & 0 deletions src/Humans.Infrastructure/Data/ContainersDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Humans.Domain.Entities;
using Humans.Infrastructure.Data.Configurations.Containers;
using Microsoft.EntityFrameworkCore;

namespace Humans.Infrastructure.Data;

/// <summary>
/// Per-section database context for the Containers section
/// (nobodies-collective/Humans#858): maps only <c>containers</c> and
/// <c>container_placements</c>, with its own
/// <c>__EFMigrationsHistory_Containers</c> table and migrations under
/// <c>Migrations/Containers/</c>. Same database, same connection — the split
/// is a code-side partition of the EF model.
/// </summary>
/// <remarks>
/// Internal-sealed like <see cref="HumansDbContext"/> (issue #750): repositories
/// are the only consumers. Configurations are applied explicitly (not by
/// assembly scanning) so this model can never accrete another section's tables.
/// </remarks>
internal sealed class ContainersDbContext(DbContextOptions<ContainersDbContext> options)
: DbContext(options)
{
public DbSet<Container> Containers => Set<Container>();
public DbSet<ContainerPlacement> ContainerPlacements => Set<ContainerPlacement>();

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);

builder.ApplyConfiguration(new ContainerConfiguration());
builder.ApplyConfiguration(new ContainerPlacementConfiguration());
}
}
33 changes: 33 additions & 0 deletions src/Humans.Infrastructure/Data/ContainersDbContextFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace Humans.Infrastructure.Data;

/// <summary>
/// Design-time factory used by <c>dotnet ef … --context ContainersDbContext</c>.
/// Mirrors <see cref="HumansDbContextFactory"/>; the migrations-history table must
/// match the runtime registration so CI's from-scratch apply records baselines in
/// <c>__EFMigrationsHistory_Containers</c>.
/// </summary>
internal sealed class ContainersDbContextFactory : IDesignTimeDbContextFactory<ContainersDbContext>
{
public ContainersDbContext CreateDbContext(string[] args)
{
var connectionString =
Environment.GetEnvironmentVariable("ConnectionStrings__DefaultConnection")
?? "Host=localhost;Database=humans_design_time;Username=humans;Password=humans";

var optionsBuilder = new DbContextOptionsBuilder<ContainersDbContext>();
optionsBuilder.UseNpgsql(
connectionString,
npgsqlOptions =>
{
npgsqlOptions.UseNodaTime();
npgsqlOptions.MigrationsAssembly("Humans.Infrastructure");
npgsqlOptions.MigrationsHistoryTable("__EFMigrationsHistory_Containers");
npgsqlOptions.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
});

return new ContainersDbContext(optionsBuilder.Options);
}
}
3 changes: 1 addition & 2 deletions src/Humans.Infrastructure/Data/HumansDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ internal sealed class HumansDbContext(DbContextOptions<HumansDbContext> options)
public DbSet<CampImage> CampImages => Set<CampImage>();
public DbSet<CampSettings> CampSettings => Set<CampSettings>();
public DbSet<CampMember> CampMembers => Set<CampMember>();
public DbSet<Container> Containers => Set<Container>();
public DbSet<ContainerPlacement> ContainerPlacements => Set<ContainerPlacement>();
public DbSet<CampRoleDefinition> CampRoleDefinitions => Set<CampRoleDefinition>();
public DbSet<CampRoleAssignment> CampRoleAssignments => Set<CampRoleAssignment>();
public DbSet<CampPolygon> CampPolygons => Set<CampPolygon>();
Expand Down Expand Up @@ -140,6 +138,7 @@ public DbSet<HoldedExpenseOutboxEvent> HoldedExpenseOutboxEvents
private static readonly string[] PeeledConfigurationNamespaces =
[
typeof(Configurations.SystemSettings.SystemSettingConfiguration).Namespace!,
typeof(Configurations.Containers.ContainerConfiguration).Namespace!,
];

protected override void OnModelCreating(ModelBuilder builder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static IServiceCollection AddHumansPersistence(
// Per-section contexts (nobodies-collective/Humans#858), migrated after
// HumansDbContext by DatabaseMigrationHostedService in registration order.
services.AddSectionDbContext<SystemSettingsDbContext>(sentinelTable: "system_settings");
services.AddSectionDbContext<ContainersDbContext>(sentinelTable: "containers");

services.AddHostedService<DatabaseMigrationHostedService>();

Expand Down
Loading
Loading