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 ContainersDbContext AgentDbContext ExpensesDbContext FinanceDbContext SurveysDbContext; do
for ctx in HumansDbContext SystemSettingsDbContext ContainersDbContext AgentDbContext ExpensesDbContext FinanceDbContext SurveysDbContext EventGuideDbContext; 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 ContainersDbContext AgentDbContext ExpensesDbContext FinanceDbContext SurveysDbContext; do
for ctx in SystemSettingsDbContext ContainersDbContext AgentDbContext ExpensesDbContext FinanceDbContext SurveysDbContext EventGuideDbContext; 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 ContainersDbContext AgentDbContext ExpensesDbContext FinanceDbContext SurveysDbContext; do
for ctx in HumansDbContext SystemSettingsDbContext ContainersDbContext AgentDbContext ExpensesDbContext FinanceDbContext SurveysDbContext EventGuideDbContext; do
dotnet ef migrations has-pending-model-changes \
--context "$ctx" \
--project src/Humans.Infrastructure \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ candidates — **(a)** re-expressed in the baseline, **(b)** dead, with justific
| Finance | `HoldedActuals`: InsertData holded_sync_states singleton | **(a) via model**: `HoldedSyncState.HasData` |
| Store | — none — | n/a |
| Surveys | — none — | n/a |
| EventGuide | `AddEventsSection`: InsertData event_categories (11 rows) | **(a) via model**: `EventCategory.HasData` |
| EventGuide | `AddEventsSection`: InsertData event_categories (8 rows) | **(a) via model**: `EventCategory.HasData` |

Every seed a candidate section owns is **model-level `HasData`**, so real-up baselines regenerate
them with zero hand work; on existing DBs the fake-applied baseline never re-inserts (no duplicate
Expand Down Expand Up @@ -253,7 +253,7 @@ all nine candidate sections:
| Gate | `gate_staff_pins.AdminEnrolled DEFAULT false` (from `20260701005052_AddGateStaffPinAdminEnrolled`) | **no** | **DEFERRED** |
| Store | `store_orders.Year DEFAULT 0` | **no** | **DEFERRED** |
| Expenses | `expense_lines.LineType DEFAULT 'Receipt'` | yes (`HasDefaultValue`) | clean |
| Surveys | 7 jsonb `DEFAULT '{}'` columns | yes (`HasDefaultValueSql`) | clean |
| Surveys | 8 jsonb `DEFAULT '{}'` columns | yes (`HasDefaultValueSql`) | clean |
| SystemSettings, Containers, Agent, Finance, EventGuide | none | n/a | clean |

**Gate and Store are deferred out of this run.** Options for unblocking them (Peter's call — all
Expand Down Expand Up @@ -319,7 +319,7 @@ Order (criteria: navs = 0 for all, so ranked by table count, then seeds/PK quirk
| 4 | `858/04-expenses` | Expenses | 4 | dead data-op disposition (§5); `LineType` default is model-declared |
| 5 | `858/05-finance` | Finance | 5 | `HasData`, identity int PK |
| 6 | `858/06-surveys` | Surveys | 6 | owned/JSON survey config; jsonb defaults model-declared |
| 7 | `858/07-eventguide` | EventGuide | 7 | `HasData` (11 seed rows) |
| 7 | `858/07-eventguide` | EventGuide | 7 | `HasData` (8 seed rows) |
| — | *(deferred)* | Gate | 3 | **§5.1 wall**: `AdminEnrolled` physical default not in model |
| — | *(deferred)* | Store | 6 | **§5.1 wall**: `Year` physical default not in model |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventCategoryConfiguration : IEntityTypeConfiguration<EventCategory>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventConfiguration : IEntityTypeConfiguration<Event>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventFavouriteConfiguration : IEntityTypeConfiguration<EventFavourite>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventGuideSettingsConfiguration : IEntityTypeConfiguration<EventGuideSettings>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventModerationActionConfiguration : IEntityTypeConfiguration<EventModerationAction>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventPreferenceConfiguration : IEntityTypeConfiguration<EventPreference>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Humans.Infrastructure.Data.Configurations;
namespace Humans.Infrastructure.Data.Configurations.EventGuide;

public class EventVenueConfiguration : IEntityTypeConfiguration<EventVenue>
{
Expand Down
47 changes: 47 additions & 0 deletions src/Humans.Infrastructure/Data/EventGuideDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Humans.Domain.Entities;
using Humans.Infrastructure.Data.Configurations.EventGuide;
using Microsoft.EntityFrameworkCore;

namespace Humans.Infrastructure.Data;

/// <summary>
/// Per-section database context for the EventGuide section
/// (nobodies-collective/Humans#858): maps only <c>events</c>,
/// <c>event_categories</c>, <c>event_venues</c>, <c>event_guide_settings</c>,
/// <c>event_moderation_actions</c>, <c>event_favourites</c> and
/// <c>event_preferences</c>, with its own
/// <c>__EFMigrationsHistory_EventGuide</c> table and migrations under
/// <c>Migrations/EventGuide/</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.
/// The Shifts-owned <c>event_settings</c> and <c>event_participations</c> tables
/// stay in <see cref="HumansDbContext"/> and are deliberately absent here.
/// </remarks>
internal sealed class EventGuideDbContext(DbContextOptions<EventGuideDbContext> options)
: DbContext(options)
{
public DbSet<EventGuideSettings> EventGuideSettings => Set<EventGuideSettings>();
public DbSet<EventCategory> EventCategories => Set<EventCategory>();
public DbSet<EventVenue> EventVenues => Set<EventVenue>();
public DbSet<Event> Events => Set<Event>();
public DbSet<EventModerationAction> EventModerationActions => Set<EventModerationAction>();
public DbSet<EventPreference> EventPreferences => Set<EventPreference>();
public DbSet<EventFavourite> EventFavourites => Set<EventFavourite>();

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

builder.ApplyConfiguration(new EventGuideSettingsConfiguration());
builder.ApplyConfiguration(new EventCategoryConfiguration());
builder.ApplyConfiguration(new EventVenueConfiguration());
builder.ApplyConfiguration(new EventConfiguration());
builder.ApplyConfiguration(new EventModerationActionConfiguration());
builder.ApplyConfiguration(new EventPreferenceConfiguration());
builder.ApplyConfiguration(new EventFavouriteConfiguration());
}
}
33 changes: 33 additions & 0 deletions src/Humans.Infrastructure/Data/EventGuideDbContextFactory.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 EventGuideDbContext</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_EventGuide</c>.
/// </summary>
internal sealed class EventGuideDbContextFactory : IDesignTimeDbContextFactory<EventGuideDbContext>
{
public EventGuideDbContext CreateDbContext(string[] args)
{
var connectionString =
Environment.GetEnvironmentVariable("ConnectionStrings__DefaultConnection")
?? "Host=localhost;Database=humans_design_time;Username=humans;Password=humans";

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

return new EventGuideDbContext(optionsBuilder.Options);
}
}
8 changes: 1 addition & 7 deletions src/Humans.Infrastructure/Data/HumansDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,6 @@ internal sealed class HumansDbContext(DbContextOptions<HumansDbContext> options)
public DbSet<ShiftSignup> ShiftSignups => Set<ShiftSignup>();
public DbSet<VolunteerEventProfile> VolunteerEventProfiles => Set<VolunteerEventProfile>();
public DbSet<GeneralAvailability> GeneralAvailability => Set<GeneralAvailability>();
public DbSet<EventGuideSettings> EventGuideSettings => Set<EventGuideSettings>();
public DbSet<EventCategory> EventCategories => Set<EventCategory>();
public DbSet<EventVenue> EventVenues => Set<EventVenue>();
public DbSet<Event> Events => Set<Event>();
public DbSet<EventModerationAction> EventModerationActions => Set<EventModerationAction>();
public DbSet<EventPreference> EventPreferences => Set<EventPreference>();
public DbSet<EventFavourite> EventFavourites => Set<EventFavourite>();
public DbSet<VolunteerBuildStatus> VolunteerBuildStatuses => Set<VolunteerBuildStatus>();
public DbSet<FeedbackReport> FeedbackReports => Set<FeedbackReport>();
public DbSet<FeedbackMessage> FeedbackMessages => Set<FeedbackMessage>();
Expand Down Expand Up @@ -122,6 +115,7 @@ internal sealed class HumansDbContext(DbContextOptions<HumansDbContext> options)
typeof(Configurations.Expenses.ExpenseReportConfiguration).Namespace!,
typeof(Configurations.Finance.HoldedExpenseDocConfiguration).Namespace!,
typeof(Configurations.Surveys.SurveyConfiguration).Namespace!,
typeof(Configurations.EventGuide.EventConfiguration).Namespace!,
];

protected override void OnModelCreating(ModelBuilder builder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static IServiceCollection AddHumansPersistence(
services.AddSectionDbContext<ExpensesDbContext>(sentinelTable: "expense_reports");
services.AddSectionDbContext<FinanceDbContext>(sentinelTable: "holded_expense_docs");
services.AddSectionDbContext<SurveysDbContext>(sentinelTable: "surveys");
services.AddSectionDbContext<EventGuideDbContext>(sentinelTable: "events");

services.AddHostedService<DatabaseMigrationHostedService>();

Expand Down
Loading
Loading