feat: add locked new-year rollover wizard for season transitions

Promote returning students, assign officers, and clear last season's data after an automatic SQLite backup, with Docker volume path docs fixed for /app/Data.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-14 14:18:18 -04:00
co-authored by Cursor
parent c5c0f95f60
commit afdabd179a
16 changed files with 1677 additions and 50 deletions
+3 -46
View File
@@ -3,10 +3,10 @@
@using WebApp.Authentication
@using WebApp.Models
@using WebApp.Components.Shared.Components
@using System.Text.Json
@using WebApp.Services
@using Core.Models
@inject IWebHostEnvironment Environment
@inject IConfiguration Configuration
@inject IChapterSettingsWriter ChapterSettingsWriter
@rendermode InteractiveServer
@@ -125,19 +125,10 @@
protected override void OnInitialized()
{
// Load from IConfiguration
_settings = Configuration.GetSection("ChapterSettings").Get<Models.ChapterSettings>()
?? new Models.ChapterSettings();
}
private string GetAppSettingsPath()
{
return Path.Combine(
Environment.ContentRootPath,
"Data",
"appsettings.json");
}
private async Task SaveSettings()
{
if (_settings == null) return;
@@ -147,41 +138,7 @@
try
{
var appSettingsPath = GetAppSettingsPath();
// Ensure Data directory exists
var dataDir = Path.GetDirectoryName(appSettingsPath);
if (dataDir != null && !Directory.Exists(dataDir))
{
Directory.CreateDirectory(dataDir);
}
// Read existing appsettings or create new
JsonDocument? existingDoc = null;
Dictionary<string, object?> settings;
if (File.Exists(appSettingsPath))
{
var existingJson = await File.ReadAllTextAsync(appSettingsPath);
existingDoc = JsonDocument.Parse(existingJson);
settings = JsonSerializer.Deserialize<Dictionary<string, object?>>(existingJson)
?? new Dictionary<string, object?>();
}
else
{
settings = new Dictionary<string, object?>();
}
// Update ChapterSettings section
settings["ChapterSettings"] = _settings;
// Write back to file
var options = new JsonSerializerOptions { WriteIndented = true };
var json = JsonSerializer.Serialize(settings, options);
await File.WriteAllTextAsync(appSettingsPath, json);
existingDoc?.Dispose();
await ChapterSettingsWriter.WriteAsync(_settings);
_statusMessage = "Settings saved successfully! Changes will take effect on next application restart.";
_statusSeverity = Severity.Success;
}