From 637be701ea34706e91c7ae65831d53beb3e75183 Mon Sep 17 00:00:00 2001 From: Scott Pouliot Date: Tue, 12 May 2026 21:08:14 -0400 Subject: [PATCH] PR 4: Production guardrails for Seed Data and Storage Migration - SeedData/Index: added prominent danger banner when running in Production (environment include="Production") so operators are clearly warned before writing to the live database; page remains accessible since seeding is occasionally valid in prod for new company onboarding - StorageMigration/Index: added warning banner in Production explaining the tool is not needed now that Azure Blob migration is complete - PlatformAdminController: hide Storage Migration hub card in Production via ShowStorageMigration flag (same WEBSITE_SITE_NAME pattern as ShowRawLogFiles); Seed Data card remains visible so prod onboarding stays reachable Co-Authored-By: Claude Sonnet 4.6 --- .../Controllers/PlatformAdminController.cs | 28 ++++++++++++------- .../Views/SeedData/Index.cshtml | 10 +++++++ .../Views/StorageMigration/Index.cshtml | 10 +++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/PowderCoating.Web/Controllers/PlatformAdminController.cs b/src/PowderCoating.Web/Controllers/PlatformAdminController.cs index 045f9e6..e4094e5 100644 --- a/src/PowderCoating.Web/Controllers/PlatformAdminController.cs +++ b/src/PowderCoating.Web/Controllers/PlatformAdminController.cs @@ -9,6 +9,7 @@ namespace PowderCoating.Web.Controllers; public class PlatformAdminController : Controller { private static readonly bool ShowRawLogFiles = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")); + private static readonly bool ShowStorageMigration = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")); public IActionResult TenantsBilling() => View(BuildTenantsBillingHub()); @@ -94,21 +95,28 @@ public class PlatformAdminController : Controller }; } - private static PlatformAdminHubViewModel BuildMaintenanceHub() => new() + private static PlatformAdminHubViewModel BuildMaintenanceHub() { - Title = "Maintenance", - PageIcon = "bi-wrench-adjustable-circle", - Intro = "Use these tools for exceptional maintenance work, migration tasks, and destructive admin operations. They are not routine day-to-day workflows.", - WarningTitle = "Use With Care", - WarningMessage = "These tools can expose bulk data, change platform state, or permanently remove records. Use them deliberately and preferably with a written reason or ticket.", - Cards = new List + var cards = new List { Card("Data Export", "Export a tenant company's data set for audits, offboarding, support, or migration work.", "DataExport", "Index", "bi-file-earmark-arrow-down", "Maintenance", SubtleBadge("warning")), Card("Data Purge", "Permanently delete soft-deleted records after previewing impact and cutoff windows.", "DataPurge", "Index", "bi-trash3", "Dangerous", SubtleBadge("danger")), - Card("Storage Migration", "Run one-off migration of local media files into cloud storage.", "StorageMigration", "Index", "bi-cloud-upload", "One-off", SubtleBadge("info")), Card("Seed Data", "Seed or remove system and demo data for setup, QA, or controlled test scenarios.", "SeedData", "Index", "bi-database-fill-gear", "Restricted", SubtleBadge("danger")) - } - }; + }; + + if (ShowStorageMigration) + cards.Insert(2, Card("Storage Migration", "Run one-off migration of local media files into cloud storage.", "StorageMigration", "Index", "bi-cloud-upload", "One-off", SubtleBadge("info"))); + + return new PlatformAdminHubViewModel + { + Title = "Maintenance", + PageIcon = "bi-wrench-adjustable-circle", + Intro = "Use these tools for exceptional maintenance work, migration tasks, and destructive admin operations. They are not routine day-to-day workflows.", + WarningTitle = "Use With Care", + WarningMessage = "These tools can expose bulk data, change platform state, or permanently remove records. Use them deliberately and preferably with a written reason or ticket.", + Cards = cards + }; + } private static PlatformAdminLinkCardViewModel Card( string title, diff --git a/src/PowderCoating.Web/Views/SeedData/Index.cshtml b/src/PowderCoating.Web/Views/SeedData/Index.cshtml index fd459e9..5be6ccb 100644 --- a/src/PowderCoating.Web/Views/SeedData/Index.cshtml +++ b/src/PowderCoating.Web/Views/SeedData/Index.cshtml @@ -24,6 +24,16 @@ + +
+ +
+
You are running in Production
+
Seed operations write data directly to the live database. Only proceed if you have a specific, intentional reason — for example, onboarding a new company. Do not seed the default demo company in production.
+
+
+
+ @if (TempData["SuccessMessage"] != null) { + +
+ +
+
This tool is not needed in Production
+
The platform has already migrated to Azure Blob Storage. Running this migration again in production is unnecessary and may cause unintended side effects. If you believe there is a specific reason to proceed, verify with the team first.
+
+
+
+