diff --git a/docs/training-notice.md b/docs/training-notice.md index 43da0b6..a4d1287 100644 --- a/docs/training-notice.md +++ b/docs/training-notice.md @@ -11,10 +11,11 @@ fails a test. A reworded notice is version 2, with its own pinned hash. ## Before deploy -Delete every row from `ConsentReceipts` (and confirm the table is empty) on any database that ever ran main at or after -`33be966`, before deploying this. Old version 1 receipts were given to different words and would otherwise count as -agreement to these. Meta/ops must confirm that nothing was ever deployed with receipts in it; if something was, this step is -required there and the people who agreed are asked again on their next chat sign-in. +Migration `20261111120000_ClearLegacyConsentReceipts` deletes every row from `ConsentReceipts` when it runs, because +version 1 receipts were given to different words and must not count as agreement to these. Manual emptying is therefore only +a belt-and-braces check: confirm the table is empty after the migrate on any database that ever ran main at or after +`33be966`. Meta/ops must still confirm whether anything was deployed with receipts in it; if so, the people who agreed are +asked again on their next chat sign-in. ## What the notice says and why diff --git a/src/Bifrost.Web/Data/Migrations/20261111120000_ClearLegacyConsentReceipts.cs b/src/Bifrost.Web/Data/Migrations/20261111120000_ClearLegacyConsentReceipts.cs new file mode 100644 index 0000000..985be6a --- /dev/null +++ b/src/Bifrost.Web/Data/Migrations/20261111120000_ClearLegacyConsentReceipts.cs @@ -0,0 +1,26 @@ +using Bifrost.Web.Data; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Bifrost.Web.Data.Migrations +{ + // Hand-written like AddMembershipSuspensionReason: data only, so no schema change and the snapshot is untouched. + // Notice v1 was reused for new words, so any receipt written against the earlier v1 text must not count as agreement + // to these. Every row goes; people who agreed are asked again on their next chat sign-in. + [DbContext(typeof(BifrostDbContext))] + [Migration("20261111120000_ClearLegacyConsentReceipts")] + public partial class ClearLegacyConsentReceipts : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql("DELETE FROM \"ConsentReceipts\";"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + // Deleted agreements cannot be restored, and must not be. + } + } +} diff --git a/tests/Bifrost.Web.Tests/MigrationDiscoveryTests.cs b/tests/Bifrost.Web.Tests/MigrationDiscoveryTests.cs index 012b061..6d902cb 100644 --- a/tests/Bifrost.Web.Tests/MigrationDiscoveryTests.cs +++ b/tests/Bifrost.Web.Tests/MigrationDiscoveryTests.cs @@ -27,6 +27,7 @@ public sealed class MigrationDiscoveryTests "20261111090000_AddConsentReceipts", "20261111100000_ConsentReceiptsOneLivePerVersion", "20261111110000_AddMembershipSuspensionReason", + "20261111120000_ClearLegacyConsentReceipts", ]; // Database.GetMigrations() reads assembly metadata only; no connection is opened.