refactor(audit): consolidate query-param parsers; widen CLI export to multi-value
This commit is contained in:
79
src/ScadaLink.Commons/Types/Audit/AuditQueryParamParsers.cs
Normal file
79
src/ScadaLink.Commons/Types/Audit/AuditQueryParamParsers.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
namespace ScadaLink.Commons.Types.Audit;
|
||||
|
||||
/// <summary>
|
||||
/// Shared lax parsers for the multi-value Audit Log query parameters
|
||||
/// (<c>channel</c>/<c>kind</c>/<c>status</c>/<c>site</c>). The Audit Log filter
|
||||
/// wire-contract is consumed by three surfaces that MUST stay in lockstep:
|
||||
/// <list type="bullet">
|
||||
/// <item>the ManagementService <c>/api/audit/query</c> + <c>/api/audit/export</c>
|
||||
/// endpoints,</item>
|
||||
/// <item>the CentralUI <c>/api/centralui/audit/export</c> endpoint, and</item>
|
||||
/// <item>the CentralUI <c>AuditLogPage</c> query-string drill-in parser.</item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para>
|
||||
/// Each caller extracts the raw repeated values for a single parameter from its
|
||||
/// own request type (ASP.NET <c>IQueryCollection</c>, a
|
||||
/// <c>Dictionary<string, StringValues></c> from <c>QueryHelpers.ParseQuery</c>,
|
||||
/// etc.) and passes them here as a plain <see cref="IEnumerable{T}"/> of strings —
|
||||
/// so this helper carries NO ASP.NET / <c>Microsoft.Extensions.Primitives</c>
|
||||
/// dependency and can live in <c>ScadaLink.Commons</c>.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// <b>Lax-parse contract.</b> Every value of a repeated parameter is parsed
|
||||
/// independently; an unparseable or blank element is silently dropped (NO 400)
|
||||
/// rather than failing the whole set. An empty result collapses to <c>null</c> so
|
||||
/// the corresponding filter dimension stays unconstrained.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static class AuditQueryParamParsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses each raw value as <typeparamref name="TEnum"/> (case-insensitive),
|
||||
/// dropping unparseable values silently. Returns <c>null</c> when
|
||||
/// <paramref name="rawValues"/> is <c>null</c>, empty, or yields no parseable
|
||||
/// value — so the filter dimension stays unconstrained.
|
||||
/// </summary>
|
||||
public static IReadOnlyList<TEnum>? ParseEnumList<TEnum>(IEnumerable<string?>? rawValues)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
if (rawValues is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var parsed = new List<TEnum>();
|
||||
foreach (var raw in rawValues)
|
||||
{
|
||||
if (Enum.TryParse<TEnum>(raw, ignoreCase: true, out var value))
|
||||
{
|
||||
parsed.Add(value);
|
||||
}
|
||||
}
|
||||
return parsed.Count > 0 ? parsed : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trims each raw value and drops blank entries. Returns <c>null</c> when
|
||||
/// <paramref name="rawValues"/> is <c>null</c>, empty, or every value was
|
||||
/// blank.
|
||||
/// </summary>
|
||||
public static IReadOnlyList<string>? ParseStringList(IEnumerable<string?>? rawValues)
|
||||
{
|
||||
if (rawValues is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var parsed = new List<string>();
|
||||
foreach (var raw in rawValues)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(raw))
|
||||
{
|
||||
parsed.Add(raw.Trim());
|
||||
}
|
||||
}
|
||||
return parsed.Count > 0 ? parsed : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user