feat(user): add the Users.IsActive column so a login can be disabled (#956) - #957
Merged
Merged
Conversation
…956) Step 2 of refusing login to resigned accounts. Bumps BasePn to 10.0.35 (which carries EformUser.IsActive), maps it with HasDefaultValue(true), and adds the column as tinyint(1) NOT NULL DEFAULT 1. defaultValue: true is load-bearing in two directions. It backfills every existing account as enabled -- a false default would lock out the entire user base on migrate -- and it keeps a rolling deploy safe: pods still on BasePn 10.0.34 have no IsActive in their model, so their INSERTs omit the column and the store default catches them. The migration is hand-written rather than scaffolded. "dotnet ef migrations add" sweeps in four unrelated InsertData operations for the CMS menu seed, which lives in HasData but was applied to databases by raw SQL in 20260319062110_AddCmsMenuItem instead. Shipping those would fail with duplicate primary keys on every tenant. The snapshot and designer therefore carry only the new property; verified with EF's own model differ that designer -> snapshot is zero operations, so the next scaffold sees no spurious IsActive diff. Tests cover the mapping and the three round trips that matter: a new account is created enabled (which is what proves the "= true" initializer and the column default agree), an explicitly disabled account stays disabled, and disabling an existing one persists. Observed failing before the mapping and migration existed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
A missing metadata namespace import causes a test compile failure, and legacy-row backfill coverage is still needed.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds EformUser.IsActive support so user logins can be disabled.
Changes:
- Pins BasePn to 10.0.35.
- Maps and migrates
IsActivewith a default oftrue. - Adds persistence and mapping tests.
File summaries
| File | Summary |
|---|---|
Microting.EformAngularFrontendBase/Migrations/BaseDbContextModelSnapshot.cs |
Records the new property. |
Microting.EformAngularFrontendBase/Migrations/20260917085145_AddIsActiveToUser.Designer.cs |
Captures the migration model. |
Microting.EformAngularFrontendBase/Migrations/20260917085145_AddIsActiveToUser.cs |
Adds the non-nullable column with a true default. |
Microting.EformAngularFrontendBase/Microting.EformAngularFrontendBase.csproj |
Updates the BasePn dependency. |
Microting.EformAngularFrontendBase/Infrastructure/Data/BaseDbContext.cs |
Configures the property mapping and default. |
Microting.EformAngularFrontendBase.Tests/UserIsActiveTests.cs |
Tests mapping and persistence behavior. |
Review details
- Files reviewed: 5/6 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| using System; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.EntityFrameworkCore; |
Comment on lines
+15
to
+20
| migrationBuilder.AddColumn<bool>( | ||
| name: "IsActive", | ||
| table: "Users", | ||
| type: "tinyint(1)", | ||
| nullable: false, | ||
| defaultValue: true); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #956. Step 2 of 4 — design: microting/eform-angular-frontend#8072 (spec PR #8073). Step 1 shipped
EformUser.IsActivein BasePn 10.0.35 (microting/eFormApi.BasePn#972).Bumps the BasePn pin 10.0.33 → 10.0.35, maps the property with
HasDefaultValue(true), adds the column astinyint(1) NOT NULL DEFAULT 1, and covers the behaviour with four tests.EformUser.IsActiveis a public property on the entity, so EF maps it by convention the moment BasePn ≥ 10.0.35 is anywhere on the load path — the explicit mapping in this PR is not what puts it in the model. NuGet resolves the highest version across the whole graph, so if any single plugin bumps BasePn to 10.0.35 before the host has this migration applied,BaseDbContext's model gainsIsActive, the schema does not have it, and every query againstUsers— login included — fails withUnknown column 'u.IsActive'on every tenant.Order: release this package → sweep the schemas → then let anything else bump BasePn. This csproj pins BasePn 10.0.35, so taking the new base package always drags the property and the migration together; keep that coupling.
Why the migration is hand-written
dotnet ef migrations addsweeps in four unrelatedInsertDataoperations for the CMS menu seed. That data lives inHasDataunderInfrastructure/Data/Seed/SeedItems/but was applied to databases by raw SQL in20260319062110_AddCmsMenuItemwithWHERE NOT EXISTSguards — so the snapshot never learned about it, and there is a permanent 4-operation pending diff onmaster.Shipping those operations would insert
MenuTemplates/MenuItemswith hardcodedId = 13into tenants that already have those rows: duplicate primary key, on all 238 schemas. So the snapshot and.Designer.cscarry only the new property.Verified with EF's own
IMigrationsModelDiffer: designer → snapshot is 0 operations, so the next developer's scaffold sees no spuriousIsActivediff. (It will still see the CMS drift — that landmine is pre-existing and is being filed separately.)Safety on production tables
AFTERclause, so MariaDB 10.3+/MySQL 8.0.12+ takeALGORITHM=INSTANT— metadata only, row count irrelevant.ALTER TABLE \Users` ADD `IsActive` tinyint(1) NOT NULL DEFAULT TRUE;`.lock_wait_timeout; a long-running transaction holding a shared MDL onUserswould otherwise queue every subsequent query behind the blockedALTER.ALTERand the__EFMigrationsHistoryinsert leaves the column present and unrecorded; the retry then fails withDuplicate column name. If that happens on a tenant, insert the history row rather than re-running.Tests
Four, observed failing before the mapping and migration existed, then passing; full suite 90/90 locally (testcontainers MariaDB, real migration chain,
AsNoTracking()on every read so nothing passes vacuously):= trueinitializer and the column default agree; it fails if either the initializer is dropped,defaultValuebecomes false, ordefaultValueis dropped entirelyNot covered: the backfill of pre-existing rows, because
Database.Migrate()always runs the chain against an empty database. Verified by hand against a MariaDB container (3 of 3 legacy rows → 1), and the samedefaultValue: truethat does the backfill is what the second test pins.🤖 Generated with Claude Code