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>
68 lines
2.3 KiB
C#
68 lines
2.3 KiB
C#
using System.Text.Json;
|
|
using WebApp.Models;
|
|
|
|
namespace WebApp.Services;
|
|
|
|
/// <summary>
|
|
/// Persists chapter settings to <c>Data/appsettings.json</c>.
|
|
/// </summary>
|
|
public class ChapterSettingsWriter : IChapterSettingsWriter
|
|
{
|
|
private readonly IWebHostEnvironment _environment;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly ILogger<ChapterSettingsWriter> _logger;
|
|
|
|
public ChapterSettingsWriter(
|
|
IWebHostEnvironment environment,
|
|
IConfiguration configuration,
|
|
ILogger<ChapterSettingsWriter> logger)
|
|
{
|
|
_environment = environment;
|
|
_configuration = configuration;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task WriteAsync(ChapterSettings settings, CancellationToken cancellationToken = default)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(settings);
|
|
|
|
var appSettingsPath = GetAppSettingsPath();
|
|
var dataDir = Path.GetDirectoryName(appSettingsPath);
|
|
if (dataDir != null && !Directory.Exists(dataDir))
|
|
{
|
|
Directory.CreateDirectory(dataDir);
|
|
}
|
|
|
|
Dictionary<string, object?> root;
|
|
if (File.Exists(appSettingsPath))
|
|
{
|
|
var existingJson = await File.ReadAllTextAsync(appSettingsPath, cancellationToken);
|
|
root = JsonSerializer.Deserialize<Dictionary<string, object?>>(existingJson)
|
|
?? [];
|
|
}
|
|
else
|
|
{
|
|
root = [];
|
|
}
|
|
|
|
root["ChapterSettings"] = settings;
|
|
|
|
var options = new JsonSerializerOptions { WriteIndented = true };
|
|
var json = JsonSerializer.Serialize(root, options);
|
|
await File.WriteAllTextAsync(appSettingsPath, json, cancellationToken);
|
|
|
|
_logger.LogInformation("Chapter settings written to {Path}", appSettingsPath);
|
|
}
|
|
|
|
public async Task UpdateCompetitionYearAsync(string competitionYear, CancellationToken cancellationToken = default)
|
|
{
|
|
var settings = _configuration.GetSection("ChapterSettings").Get<ChapterSettings>()
|
|
?? new ChapterSettings();
|
|
settings.CompetitionYear = competitionYear;
|
|
await WriteAsync(settings, cancellationToken);
|
|
}
|
|
|
|
private string GetAppSettingsPath() =>
|
|
Path.Combine(_environment.ContentRootPath, "Data", "appsettings.json");
|
|
}
|