Add XML documentation for improved code clarity

Added detailed XML documentation across multiple files to enhance
code maintainability and readability. Key updates include:

- Documented `AllowAllDashboardAuthorizationFilter` to clarify
  its development-only usage.
- Added comments to `DtoExtensions` for Hangfire job ID generation
  and DTO-to-command conversion methods.
- Enhanced `HealthCheckHtmlGenerator` with detailed descriptions
  of HTML generation methods and utility functions.
- Documented `DependencyInjection` and `ProfileWorkerOptionsValidator`
  to explain service registration and configuration validation.
- Updated `ProfileCache` with comments on thread-safe operations.
- Added documentation to `ProfileWork` for profile synchronization
  logic and execution flow.
- Enhanced `ProfileWorker` with health check logic and background
  service execution details.
- Documented `ProfileWorkerOptions` configuration properties.

These changes aim to improve developer understanding and ensure
best practices are followed in production environments.
This commit is contained in:
2026-07-13 13:37:12 +02:00
parent 84b95c53e4
commit bc881bf70f
8 changed files with 254 additions and 5 deletions

View File

@@ -4,10 +4,32 @@ using System.Text;
namespace ECMJobRunner.WebCron.HealthCheck;
/// <summary>
/// Generates HTML representation of health check reports.
/// Generates HTML representation of ASP.NET Core health check reports.
/// Produces a Bootstrap 5-based UI with auto-refresh, status indicators, and detailed metrics.
/// </summary>
public static class HealthCheckHtmlGenerator
{
/// <summary>
/// Generates a complete HTML page for displaying health check results.
/// </summary>
/// <param name="report">The health check report containing service status information.</param>
/// <returns>A complete HTML document string ready to be sent as HTTP response.</returns>
/// <remarks>
/// The generated UI includes:
/// <list type="bullet">
/// <item><description>Navigation links to Hangfire, Serilog.UI, and health endpoints</description></item>
/// <item><description>Overall health status with color-coded badge</description></item>
/// <item><description>Summary card with total duration and check count</description></item>
/// <item><description>Individual check cards with detailed metrics and exception info</description></item>
/// <item><description>Auto-refresh countdown (10 seconds)</description></item>
/// </list>
/// External dependencies:
/// <list type="bullet">
/// <item><description>Bootstrap 5.3.0 (CDN)</description></item>
/// <item><description>/css/health-ui.css (custom styles)</description></item>
/// <item><description>/js/health-ui.js (auto-refresh logic)</description></item>
/// </list>
/// </remarks>
public static string Generate(HealthReport report)
{
var sb = new StringBuilder();
@@ -47,6 +69,10 @@ public static class HealthCheckHtmlGenerator
return sb.ToString();
}
/// <summary>
/// Appends the navigation menu with links to application dashboards.
/// </summary>
/// <param name="sb">The StringBuilder to append HTML to.</param>
private static void AppendNavigation(StringBuilder sb)
{
sb.Append(@"
@@ -66,6 +92,11 @@ public static class HealthCheckHtmlGenerator
sb.AppendLine(" </div>");
}
/// <summary>
/// Appends the overall status header showing aggregate health and timestamp.
/// </summary>
/// <param name="sb">The StringBuilder to append HTML to.</param>
/// <param name="report">The health check report.</param>
private static void AppendOverallStatus(StringBuilder sb, HealthReport report)
{
var statusClass = GetStatusClass(report.Status);
@@ -91,6 +122,11 @@ public static class HealthCheckHtmlGenerator
<div class=""col-md-4"">");
}
/// <summary>
/// Appends the summary card displaying aggregate metrics (status, duration, check count).
/// </summary>
/// <param name="sb">The StringBuilder to append HTML to.</param>
/// <param name="report">The health check report.</param>
private static void AppendSummaryCard(StringBuilder sb, HealthReport report)
{
var statusClass = GetStatusClass(report.Status);
@@ -122,6 +158,11 @@ public static class HealthCheckHtmlGenerator
<div class=""col-md-8"">");
}
/// <summary>
/// Appends individual health check result cards with detailed metrics.
/// </summary>
/// <param name="sb">The StringBuilder to append HTML to.</param>
/// <param name="report">The health check report containing check entries.</param>
private static void AppendIndividualChecks(StringBuilder sb, HealthReport report)
{
foreach (var entry in report.Entries)
@@ -175,6 +216,11 @@ public static class HealthCheckHtmlGenerator
</div>");
}
/// <summary>
/// Appends a detail table for additional health check data (e.g., timestamps, counters).
/// </summary>
/// <param name="sb">The StringBuilder to append HTML to.</param>
/// <param name="data">Dictionary of custom data provided by the health check.</param>
private static void AppendCheckDetails(StringBuilder sb, IReadOnlyDictionary<string, object> data)
{
sb.AppendLine(@"
@@ -198,6 +244,10 @@ public static class HealthCheckHtmlGenerator
</div>");
}
/// <summary>
/// Appends the auto-refresh indicator widget with countdown timer.
/// </summary>
/// <param name="sb">The StringBuilder to append HTML to.</param>
private static void AppendRefreshInfo(StringBuilder sb)
{
sb.AppendLine(@"
@@ -208,6 +258,11 @@ public static class HealthCheckHtmlGenerator
sb.AppendLine(@" </div>");
}
/// <summary>
/// Maps a health status to the corresponding CSS class name for styling.
/// </summary>
/// <param name="status">The health status.</param>
/// <returns>CSS class name (e.g., "status-healthy", "status-degraded").</returns>
private static string GetStatusClass(HealthStatus status)
{
return status switch
@@ -219,6 +274,11 @@ public static class HealthCheckHtmlGenerator
};
}
/// <summary>
/// Maps a health status to the corresponding Bootstrap badge CSS class.
/// </summary>
/// <param name="status">The health status.</param>
/// <returns>Badge CSS class name (e.g., "badge-healthy", "badge-degraded").</returns>
private static string GetBadgeClass(HealthStatus status)
{
return status switch
@@ -230,6 +290,11 @@ public static class HealthCheckHtmlGenerator
};
}
/// <summary>
/// Maps a health status to the corresponding emoji icon.
/// </summary>
/// <param name="status">The health status.</param>
/// <returns>Unicode emoji character (✅ for healthy, ⚠️ for degraded, ❌ for unhealthy).</returns>
private static string GetStatusIcon(HealthStatus status)
{
return status switch
@@ -241,6 +306,19 @@ public static class HealthCheckHtmlGenerator
};
}
/// <summary>
/// Formats health check data values for display.
/// Applies special formatting for common types (DateTime, TimeSpan).
/// </summary>
/// <param name="value">The data value to format.</param>
/// <returns>
/// Formatted string representation:
/// <list type="bullet">
/// <item><description><see cref="DateTime"/> → "yyyy-MM-dd HH:mm:ss"</description></item>
/// <item><description><see cref="TimeSpan"/> → "{seconds}s"</description></item>
/// <item><description>Other types → ToString() or "N/A" if null</description></item>
/// </list>
/// </returns>
private static string FormatDataValue(object? value)
{
if (value == null)