using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PowderCoating.Application.Interfaces; using PowderCoating.Shared.Constants; namespace PowderCoating.Web.Controllers; /// /// SuperAdmin-only tool for migrating locally stored media files from the on-disk /// media/ folder to Azure Blob Storage via /// . Intended to be run once (or a small number /// of times) during a storage-backend transition — it is not a routine operation. /// [Authorize(Policy = AppConstants.Policies.SuperAdminOnly)] public class StorageMigrationController : Controller { private readonly IStorageMigrationService _migrationService; private readonly IWebHostEnvironment _environment; public StorageMigrationController( IStorageMigrationService migrationService, IWebHostEnvironment environment) { _migrationService = migrationService; _environment = environment; } /// /// Renders the migration status page showing the local media/ path, whether /// the directory exists, and how many files it currently contains. This information /// lets operators confirm there is work to migrate before triggering the potentially /// long-running action. /// public IActionResult Index() { var mediaPath = Path.Combine(_environment.ContentRootPath, "media"); ViewBag.MediaPath = mediaPath; ViewBag.MediaExists = Directory.Exists(mediaPath); if (Directory.Exists(mediaPath)) { var fileCount = Directory.EnumerateFiles(mediaPath, "*.*", SearchOption.AllDirectories).Count(); ViewBag.LocalFileCount = fileCount; } else { ViewBag.LocalFileCount = 0; } return View(); } /// /// Executes the migration of all local media/ files to Azure Blob Storage /// and renders a Results view with the outcome. /// /// The flag controls whether source files /// are removed from disk after successful upload. It defaults to false so /// that operators can verify the migration result before committing to deletion. /// The actual upload logic is encapsulated in /// so it can be tested independently of the HTTP layer. /// /// [HttpPost] [ValidateAntiForgeryToken] public async Task Migrate(bool deleteAfterMigration = false) { var mediaPath = Path.Combine(_environment.ContentRootPath, "media"); var result = await _migrationService.MigrateFilesystemToAzureAsync(mediaPath, deleteAfterMigration); return View("Results", result); } }