Documentation modifications

This commit is contained in:
julian
2026-06-27 15:23:26 -07:00
parent a633fe6c06
commit a19fb90902
218 changed files with 2882 additions and 0 deletions
+8
View File
@@ -12,11 +12,19 @@ public sealed class AuthUtils
{
private LoginResponse _loginResponse = new();
/// <summary>
/// Static constructor that initializes the static <see cref="AuthUtils.InternalInstance"/> field of the <see cref="AuthUtils"/> class by assigning a new <see cref="AuthUtils"/> instance if it has not already been set.
/// </summary>
/// <!-- aidoc:v1 sig=b1904e8 body=05a5e0c -->
static AuthUtils()
{
InternalInstance ??= new AuthUtils();
}
/// <summary>
/// Initializes a new instance of the <see cref="AuthUtils"/> authentication utility class and stores a self-reference in <see cref="AuthUtils.InternalInstance"/>, allowing callers to retrieve the active instance through that property.
/// </summary>
/// <!-- aidoc:v1 sig=cfb2f97 body=ec96561 -->
public AuthUtils()
{
InternalInstance = this;
+7
View File
@@ -140,6 +140,13 @@ namespace adas_core.Domain.Utils
public static string ConfigObservationsAll()
=> "configObservations:all";
/// <summary>
/// Returns the cache key and its associated time-to-live (TTL) for caching the complete collection of configuration observations.
/// The TTL is resolved by <see cref="CacheKeyTtl.ResolveForEntity"/> using <paramref name="settings"/> and <see cref="CacheEnum.EntityType.ConfigObservations"/>.
/// </summary>
/// <param name="settings">Optional cache configuration used to resolve the TTL; may be <see langword="null"/>.</param>
/// <returns>A tuple containing the cache key and the resolved TTL as a <see cref="Nullable{TimeSpan}"/>.</returns>
/// <!-- aidoc:v1 sig=4708037 body=5108bf4 -->
public static (string Key, TimeSpan? Ttl) ConfigObservationsAllKeyWithTtl(
CacheSettings? settings)
{
@@ -11,6 +11,14 @@ namespace adas_core.Domain.Utils;
public static class CardConfigExtensions
{
// Método principal para extraer todos los nombres
/// <summary>
/// Retrieves all unique observation names defined within the rows and cells of the specified <see cref="CardConfig"/>.
/// Returns an empty list when <paramref name="config"/> has no <see cref="CardConfig.Rows"/>, and skips any row whose <c>Cells</c> collection is <see langword="null"/>.
/// Observation names are extracted recursively from each cell, with duplicates removed.
/// </summary>
/// <param name="config">The <see cref="CardConfig"/> whose cell observation names should be collected.</param>
/// <returns>A <see cref="List{T}"/> of distinct observation names found across all cells of <paramref name="config"/>, or an empty list if no rows are defined.</returns>
/// <!-- aidoc:v1 sig=2538759 body=b24f5d8 -->
public static List<string> GetAllObservationNames(this CardConfig config)
{
if (config.Rows == null) return [];
@@ -28,6 +36,12 @@ public static class CardConfigExtensions
}
// Método auxiliar RECURSIVO para extraer nombres de una Cell y sus SubObs
/// <summary>
/// Extracts observation names from the specified <paramref name="cell"/>, yielding the values in <see cref="Cell.ObservationName"/> when present and recursively collecting names from each <see cref="Cell.SubObs"/>.
/// </summary>
/// <param name="cell">The <see cref="Cell"/> whose observation names and nested sub-observations are traversed.</param>
/// <returns>An <see cref="IEnumerable{String}"/> of observation names from the <paramref name="cell"/> and its sub-observations.</returns>
/// <!-- aidoc:v1 sig=0831490 body=43bfafd -->
private static IEnumerable<string> ExtractObservationNames(Cell cell)
{
// 1. Si la Cell tiene ObservationName, devolver esos nombres.
@@ -26,6 +26,14 @@ public partial class ComplexObjectValueTypeSerializer : SerializerBase<object>
[GeneratedRegex("ObjectId\\((.[a-f0-9]{24}.)\\)")]
private static partial Regex ObjectIdRegex();
/// <summary>
/// Deserializes a BSON value into a .NET <see cref="object"/>, handling primitive <see cref="BsonType"/> values directly, marker types (Null, EndOfDocument, Undefined, MinKey, MaxKey) as <c>false</c>, embedded <see cref="BsonDocument"/> instances by resolving the <c>_t</c> type discriminator with legacy namespace normalization (mapping <c>adas-core.Models</c> to <c>adas-core.Domain.Models</c>), and <see cref="BsonArray"/> values as a <see cref="List{T}"/> of the inferred element type after cleaning <c>$oid</c> wrappers from the intermediate JSON.
/// </summary>
/// <param name="context">The <see cref="BsonDeserializationContext"/> whose <see cref="BsonDeserializationContext.Reader"/> supplies the BSON tokens to read.</param>
/// <param name="args">The <see cref="BsonDeserializationArgs"/> carrying additional deserialization configuration.</param>
/// <returns>An <see cref="object"/> representing the deserialized value: a primitive returned directly, <c>false</c> for marker types, an instance of the type indicated by the <c>_t</c> field for documents, or a typed <see cref="List{T}"/> for arrays.</returns>
/// <exception cref="Exception">Thrown when a <see cref="BsonDocument"/> lacks a <c>_t</c> discriminator or a <c>_v</c> array payload, the referenced <see cref="Type"/> cannot be resolved via <see cref="Type.GetType(string)"/>, the element type of a non-empty <see cref="BsonArray"/> cannot be determined, the current <see cref="BsonType"/> is unhandled, or any inner step via <see cref="JsonConvert.DeserializeObject(string, System.Type, JsonSerializerSettings)"/> fails.</exception>
/// <!-- aidoc:v1 sig=b805219 body=fc5d56f -->
public override object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
try
@@ -11,6 +11,13 @@ namespace adas_core.Domain.Utils;
public static class DetailConfigExtension
{
// Método principal para iniciar la extracción
/// <summary>
/// Retrieves all unique observation names defined in the nurse rows of the specified <paramref name="config"/>.
/// Returns an empty list when <see cref="CardDetailsConfig.NurseRows"/> is null.
/// </summary>
/// <param name="config">The <see cref="CardDetailsConfig"/> extension target whose nurse rows are inspected.</param>
/// <returns>A <see cref="List{String}"/> containing the distinct observation names extracted from the nurse rows; an empty list when no nurse rows are defined.</returns>
/// <!-- aidoc:v1 sig=1a41350 body=9520d6e -->
public static List<string> GetAllObservationNames(this CardDetailsConfig config)
{
if (config.NurseRows == null) return [];
@@ -24,6 +31,12 @@ public static class DetailConfigExtension
}
// --- Auxiliar 1: Recorre la anidación de Filas (RowDetailsConfig) ---
/// <summary>
/// Recursively extracts names from a collection of <see cref="RowDetailsConfig"/> entries, traversing both the <see cref="RowDetailsConfig.Cells"/> and nested <see cref="RowDetailsConfig.Rows"/> of each row.
/// </summary>
/// <param name="rows">The list of <see cref="RowDetailsConfig"/> instances to process.</param>
/// <returns>An <see cref="IEnumerable{T}"/> of <see cref="string"/> containing all names collected from the cells and nested rows.</returns>
/// <!-- aidoc:v1 sig=4148c6b body=c6277a5 -->
private static IEnumerable<string> ExtractNamesFromRows(List<RowDetailsConfig> rows)
{
foreach (var row in rows)
@@ -43,6 +56,12 @@ public static class DetailConfigExtension
}
// --- Auxiliar 2: Recorre la anidación de Celdas (CellDetails) ---
/// <summary>
/// Recursively extracts every observation name from a <see cref="CellDetails"/>, yielding names from the current cell as well as from all its nested <see cref="CellDetails.Cells"/>. Null <see cref="CellDetails.ObservationName"/> and null <see cref="CellDetails.Cells"/> collections are safely skipped without yielding any elements.
/// </summary>
/// <param name="cell">The <see cref="CellDetails"/> whose observation names, including those of its descendant cells, should be collected.</param>
/// <returns>A lazily evaluated <see cref="IEnumerable{T}"/> of <see cref="string"/> containing every observation name found in <paramref name="cell"/> and its nested cells.</returns>
/// <!-- aidoc:v1 sig=a01fdc1 body=25dff85 -->
private static IEnumerable<string> ExtractNamesFromCells(CellDetails cell)
{
// 1. EXTRAER nombres del nivel actual
@@ -1,5 +1,14 @@
namespace adas_core.Domain.Utils;
/// <summary>
/// Represents a sealed dictionary that inherits from <see cref="Dictionary{TKey,TValue}"/> and provides equality comparison with <see cref="ComparableDictionary{TKey,TValue}"/> instances through <see cref="IEquatable{T}"/>.
/// </summary>
/// <typeparam name="TKey">The type of the keys stored in the dictionary, constrained to be non-null.</typeparam>
/// <typeparam name="TValue">The type of the values stored in the dictionary, constrained to be non-null.</typeparam>
/// <remarks>
/// The <see cref="IEquatable{T}"/> implementation targets <see cref="ComparableDictionary{TKey,TValue}"/> rather than the declaring <see cref="EquatableDictionary{TKey,TValue}"/> type, enabling cross-type equality semantics between the two dictionary variants.
/// </remarks>
/// <!-- aidoc:v1 sig=c2a0a45 -->
public sealed class EquatableDictionary<TKey, TValue>
: Dictionary<TKey, TValue>, IEquatable<ComparableDictionary<TKey, TValue>>
where TKey : notnull where TValue : notnull
+12
View File
@@ -3,12 +3,24 @@ using System.Reflection;
namespace adas_core.Domain.Utils;
/// <summary>
/// Provides a static mapping utility for instances of the reference type <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The reference type that this mapper operates on, constrained to reference types via the <c>class</c> constraint.</typeparam>
/// <remarks>
/// As indicated by the <c>where T : class</c> constraint, only reference types can be supplied as the generic argument for <typeparamref name="T"/>.
/// </remarks>
/// <!-- aidoc:v1 sig=4a87291 -->
public static class Mapper<T>
// We can only use reference types
where T : class
{
private static readonly Dictionary<string, PropertyInfo> PropertyMap;
/// <summary>
/// Initializes the static <see cref="Mapper{T}.PropertyMap"/> cache used by the mapper to look up <see cref="System.Reflection.PropertyInfo"/> entries for the type parameter T by their lowercased property name.
/// </summary>
/// <!-- aidoc:v1 sig=ed9693b body=3dc0e55 -->
static Mapper()
{
// At this point we can convert each
+12
View File
@@ -13,6 +13,11 @@ public sealed class MappingUtils : IMappingUtils
private readonly List<MappingInterventions>? _cccData;
private bool _isTransformedValue;
/// <summary>
/// Initializes a new instance of the <see cref="MappingUtils"/> class by loading the CCC mapping interventions from the supplied <see cref="ApiSettings"/> and resetting the transformed-value flag.
/// </summary>
/// <param name="apiSettings">The <see cref="IOptions{TOptions}"/> wrapper whose <see cref="IOptions{TOptions}.Value"/> provides the <see cref="ApiSettings"/> whose <see cref="ApiSettings.MappingInterventions"/> data is stored in this instance.</param>
/// <!-- aidoc:v1 sig=396ced4 body=2be44b9 -->
public MappingUtils(IOptions<ApiSettings> apiSettings)
{
var cccMappingData = apiSettings.Value.MappingInterventions;
@@ -46,6 +51,13 @@ public sealed class MappingUtils : IMappingUtils
return null; // No se encontro el code
}*/
/// <summary>
/// Searches for an entry matching the supplied <paramref name="code"/> within the given <paramref name="category"/> and returns its associated type, name, and group. The <paramref name="code"/> may be a <see cref="double"/> (matched as an exact value or within a numeric range) or a <see cref="string"/> (parsed as a <see cref="double"/> when possible, otherwise compared as text). Returns <see langword="null"/> when no matching entry is found.
/// </summary>
/// <param name="code">The code to look up. Accepts a <see cref="double"/> for numeric matching and a <see cref="string"/> for text matching or numeric parsing.</param>
/// <param name="category">The category used to filter the entries; only entries whose category matches this value are considered.</param>
/// <returns>A tuple containing the <c>type</c>, <c>name</c>, and <c>group</c> of the matching entry, or <see langword="null"/> when no match is found.</returns>
/// <!-- aidoc:v1 sig=b69e7ef body=e42117e -->
public (string type, string name, string group)? SearchByCode(object code, string category)
{
// esta funcion conviete a double los string que permitan conversion si no se puede los deja como string
+12
View File
@@ -10,6 +10,12 @@ namespace adas_core.Domain.Utils;
/// </summary>
public class RelayHelper
{
/// <summary>
/// Retrieves the current status of a <see cref="Relay"/> by calling a local REST API endpoint built from its connection parameters, returning <see langword="true"/> when the relay is reported as active and <see langword="false"/> when the response is not <see cref="HttpStatusCode.OK"/>, the payload cannot be converted to a boolean, or any exception is raised during the request.
/// </summary>
/// <param name="relay">The <see cref="Relay"/> whose status is queried; its <see cref="Relay.RelayNumber"/> is used in the URL path while <see cref="Relay.Driver"/>, <see cref="Relay.Ip"/>, and <see cref="Relay.Port"/> are passed as query parameters.</param>
/// <returns><see langword="true"/> if the API responds with <see cref="HttpStatusCode.OK"/> and the response body converts to a boolean value of <see langword="true"/>; otherwise, <see langword="false"/>.</returns>
/// <!-- aidoc:v1 sig=0240829 body=a1db00d -->
public static bool GetRelayStatusFromApiRest(Relay relay)
{
UriBuilder builder = new()
@@ -94,6 +100,12 @@ public class RelayHelper
PowerRelay(relay, builder);
}
/// <summary>
/// Sends an HTTP POST request to power a <see cref="Relay"/> through the endpoint described by <paramref name="builder"/>, enriching the query string with the relay's driver, IP address, port, and a fixed channel count of 8. Logs an information message when the response status is not <see cref="HttpStatusCode.OK"/> and logs any exception raised during the call at debug level instead of propagating it.
/// </summary>
/// <param name="relay">The relay to power, whose <see cref="Relay.Driver"/>, <see cref="Relay.Ip"/> and <see cref="Relay.Port"/> values are written into the request query string.</param>
/// <param name="builder">The <see cref="UriBuilder"/> whose query string is populated and whose <see cref="UriBuilder.Uri"/> identifies the target endpoint of the POST request.</param>
/// <!-- aidoc:v1 sig=01d6944 body=089ce17 -->
private static void PowerRelay(Relay relay, UriBuilder builder)
{
var query = HttpUtility.ParseQueryString(builder.Query);