fix(availability): translate status messages, return stored admin reason from API

- Add AvailabilityStatusDetails record and GetStatusDetailsAsync() to
  IAvailabilityService; implement in PersistentAvailabilityService so the
  admin-set reason stored in the database is returned alongside the status
- AvailabilityController.GetStatus() now returns the stored message instead
  of hardcoded English strings
- Add messageAvailable / messageMaintenance / messageUnavailable translation
  keys in en + nl so default messages are fully translatable
- AvailabilityStatusBadge: Available always shows the translated default;
  Maintenance and Unavailable show the custom admin reason when set,
  otherwise fall back to the translated default

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 14:53:11 +02:00
co-authored by Claude Haiku 4.5
parent d69512a449
commit d8b0484803
8 changed files with 100 additions and 26 deletions
@@ -0,0 +1,6 @@
namespace SlpModularCms.Core.Availability;
/// <summary>
/// Status en optionele admin-melding van de systeembeschikbaarheid.
/// </summary>
public record AvailabilityStatusDetails(AvailabilityStatus Status, string? Message);
@@ -10,4 +10,9 @@ public interface IAvailabilityService
/// </summary>
/// <returns>De huidige <see cref="AvailabilityStatus"/>.</returns>
Task<AvailabilityStatus> IsAvailableAsync();
/// <summary>
/// Geeft de huidige status inclusief de optionele admin-melding terug.
/// </summary>
Task<AvailabilityStatusDetails> GetStatusDetailsAsync();
}
@@ -20,12 +20,12 @@ public class AvailabilityController : ControllerBase
[AllowAnonymous]
public async Task<IActionResult> GetStatus()
{
var status = await _availabilityService.IsAvailableAsync();
var details = await _availabilityService.GetStatusDetailsAsync();
return Ok(new
{
Status = status.ToString(),
Status = details.Status.ToString(),
CheckedAt = DateTimeOffset.UtcNow,
Message = string.Empty,
Message = details.Message ?? string.Empty,
});
}
@@ -54,6 +54,24 @@ public class PersistentAvailabilityService : IAvailabilityService
}
}
public async Task<AvailabilityStatusDetails> GetStatusDetailsAsync()
{
try
{
var state = await _context.AvailabilityStates.FirstOrDefaultAsync();
if (state == null)
return new AvailabilityStatusDetails(AvailabilityStatus.Available, null);
return new AvailabilityStatusDetails(state.Status, state.Message);
}
catch (Exception)
{
_lastErrorTime = DateTimeOffset.UtcNow;
_cachedStatus = AvailabilityStatus.Available;
return new AvailabilityStatusDetails(_cachedStatus, null);
}
}
/// <summary>
/// Update de globale systeemstatus.
/// </summary>