=== Summary: 675 files | 7 generated | 484 fresh | 4605 untracked | 4268 adopted | 355 marked | 466 validated-ok | 2+0 stale (sig+body) | 0 skipped | 0 failed | elapsed 11:08:11.442 (40091.44s) ===
This commit is contained in:
@@ -27,6 +27,7 @@ namespace adas_core.Application.Services;
|
||||
/// <remarks>
|
||||
/// Acts as the default service type that fulfills the configuration observation interface.
|
||||
/// </remarks>
|
||||
/// <!-- aidoc:v1 sig=b6374e4 -->
|
||||
public class ConfigObservationService : IConfigObservationService
|
||||
{
|
||||
private static readonly ConcurrentDictionary<ObjectId, ConfigObservationCached> CachedConfigObservations = new();
|
||||
@@ -96,6 +97,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="ct">A token to monitor for cancellation requests.</param>
|
||||
/// <returns>A collection of all <see cref="ConfigObservation"/> entries, sourced from cache when available or from the repository otherwise.</returns>
|
||||
/// <!-- aidoc:v1 sig=c20c545 body=6a29098 -->
|
||||
public async Task<ICollection<ConfigObservation>> GetAllConfigs(CancellationToken ct = default)
|
||||
{
|
||||
|
||||
@@ -115,6 +117,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// Retrieves a compact representation of all configuration observations by returning the total item count.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="ConfigObservationDto"/> containing the total number of configuration observations.</returns>
|
||||
/// <!-- aidoc:v1 sig=42b2f1f body=5519b7f -->
|
||||
public async Task<ConfigObservationDto> GetAllCompact()
|
||||
{
|
||||
var count = await _configObservationRepository.Count();
|
||||
@@ -126,6 +129,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="filter">The pagination filter containing the requested page number and page size used to retrieve the items and populate the response metadata.</param>
|
||||
/// <returns>A <see cref="PaginationResponse{ConfigObservation}"/> containing the items for the requested page and the total count of all available items.</returns>
|
||||
/// <!-- aidoc:v1 sig=6f51347 body=9b21a36 -->
|
||||
public async Task<PaginationResponse<ConfigObservation>> GetPaginatedItems(PaginationFilter filter)
|
||||
{
|
||||
var result = await _configObservationRepository.GetPaginatedItems(filter);
|
||||
@@ -141,6 +145,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the configuration observation to retrieve.</param>
|
||||
/// <returns>The configuration observation matching the specified identifier, or null if not found.</returns>
|
||||
/// <!-- aidoc:v1 sig=1821829 body=5e45c12 -->
|
||||
public async Task<ConfigObservation?> GetConfigById(ObjectId id)
|
||||
{
|
||||
return await _configObservationRepository.FindById(id) ?? null;
|
||||
@@ -151,6 +156,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier used to look up the related configuration names.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing the list of configuration names matching the given identifier.</returns>
|
||||
/// <!-- aidoc:v1 sig=cff8c0e body=4d4999a -->
|
||||
public async Task<List<string>> GetConfigNames(string id)
|
||||
{
|
||||
return await _configObservationRepository.GetConfigNames(id);
|
||||
@@ -160,6 +166,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// Retrieves the list of configuration names from the configuration observation repository.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a list of configuration names.</returns>
|
||||
/// <!-- aidoc:v1 sig=fee3cef body=35d2c7e -->
|
||||
public async Task<List<string>> GetConfigNames()
|
||||
{
|
||||
return await _configObservationRepository.GetConfigNames();
|
||||
@@ -172,6 +179,8 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <typeparam name="T">The patient observation type, constrained to <see cref="BasePatientObservation"/>.</typeparam>
|
||||
/// <param name="obs">The patient observation for which the retention action is being evaluated.</param>
|
||||
/// <returns>A task containing the resolved <see cref="ObservatitonRetentionResult"/>, or null when no configuration is available.</returns>
|
||||
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
|
||||
/// "The method's return type is nullable, but the code always returns a non-null ObservatitonRetentionResult (falling back to NoDelete/null-policy-value), never null. The doc claims it returns null when no configuration is available, which is incorrect." -->
|
||||
public async Task<ObservatitonRetentionResult?> RetentionActions<T>(T obs) where T : BasePatientObservation
|
||||
{
|
||||
var conf = await Get(obs);
|
||||
@@ -192,6 +201,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="min">The optional minimum reference value included in the mapping.</param>
|
||||
/// <param name="max">The optional maximum reference value included in the mapping.</param>
|
||||
/// <returns>A task that resolves to the <see cref="StatusEnum.Type"/> computed from the mapped observation, or <see cref="StatusEnum.Type.Ok"/> when no applicable configuration or mapping status is found.</returns>
|
||||
/// <!-- aidoc:v1 sig=2998c17 body=c347213 -->
|
||||
public async Task<StatusEnum.Type> GroupedObservationStatus(GroupedField groupedField,
|
||||
GroupedObservationEnum.Result result,
|
||||
string name, object value, double? min, double? max)
|
||||
@@ -228,6 +238,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="obs">The patient observation to be mapped.</param>
|
||||
/// <param name="onlyByName">If <c>true</c>, the configuration lookup is performed by name only; otherwise the full lookup is used.</param>
|
||||
/// <returns>The mapped observation, the original observation when unknown observations are allowed, or <c>null</c> when mapping is ignored or the configuration is invalid.</returns>
|
||||
/// <!-- aidoc:v1 sig=adab269 body=bb82b7b -->
|
||||
public async Task<T?> Map<T>(T obs, bool onlyByName = false) where T : BasePatientObservation
|
||||
{
|
||||
var conf = onlyByName ? await Get(obs, onlyByName) : await Get(obs);
|
||||
@@ -253,6 +264,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the configuration observation to remove.</param>
|
||||
/// <returns>The removed <see cref="ConfigObservation"/> if it was found and deleted; otherwise, <c>null</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=93970f8 body=d775460 -->
|
||||
public async Task<ConfigObservation?> RemoveConfigItem(ObjectId id)
|
||||
{
|
||||
var item = await _configObservationRepository.FindById(id);
|
||||
@@ -272,6 +284,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="treatment">The patient treatment whose requested give codes are resolved against the configuration store.</param>
|
||||
/// <returns>The original <see cref="PatientTreatment"/> if a valid configuration is found, or <c>null</c> when the treatment should be discarded.</returns>
|
||||
/// <!-- aidoc:v1 sig=b468f2f body=f7cc310 -->
|
||||
public async Task<PatientTreatment?> Map(PatientTreatment treatment)
|
||||
{
|
||||
ConfigObservation? conf = null;
|
||||
@@ -292,6 +305,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="obs">The patient observation whose matching configuration should be resolved.</param>
|
||||
/// <param name="onlyByName">When <c>true</c>, the lookup is restricted to matching by <see cref="BasePatientObservation.Name"/> only; otherwise matching also considers code, coding system, and parent observation data.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> containing the matched <see cref="ConfigObservation"/> processed via <c>Process</c>, or <c>null</c> if no configuration items are available or no match is found.</returns>
|
||||
/// <!-- aidoc:v1 sig=887109c body=724c8ab -->
|
||||
public async Task<ConfigObservation?> Get<T>(T obs, bool onlyByName = false)
|
||||
where T : BasePatientObservation
|
||||
{
|
||||
@@ -369,6 +383,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="codingSystem">The coding system identifier used to filter the observation. May be <see langword="null"/>.</param>
|
||||
/// <param name="code">The code value used to filter the observation. May be <see langword="null"/>.</param>
|
||||
/// <returns>A processed <see cref="ConfigObservation"/> if a match is found; otherwise, <see langword="null"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=35cb21e body=8c37456 -->
|
||||
public async Task<ConfigObservation?> GetByCodeSysAndCode(string? codingSystem, string? code)
|
||||
{
|
||||
var filteredResult = await _configObservationRepository.GetByCodeSysAndCode(codingSystem, code);
|
||||
@@ -384,6 +399,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the configuration to look up; if null or empty, the method returns <c>null</c>.</param>
|
||||
/// <returns>A <see cref="ConfigObservation"/> when a matching configuration is found and successfully processed; otherwise, <c>null</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=2eba3bf body=dd0b407 -->
|
||||
public async Task<ConfigObservation?> Get(string? name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return null;
|
||||
@@ -406,6 +422,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="configObservationItem">The configuration observation payload containing the identifier of the record to update.</param>
|
||||
/// <returns>The updated <see cref="ConfigObservation"/>.</returns>
|
||||
/// <exception cref="NotFoundException">Thrown when no configuration observation exists for the supplied id.</exception>
|
||||
/// <!-- aidoc:v1 sig=9196090 body=719174b -->
|
||||
public async Task<ConfigObservation?> UpdateConfig(ConfigObservation configObservationItem)
|
||||
{
|
||||
// if (!configObservationItem.Id.HasValue)
|
||||
@@ -429,6 +446,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="name">The name used to look up the configuration observation items.</param>
|
||||
/// <returns>A collection of <see cref="ConfigObservation"/> items matching the specified name.</returns>
|
||||
/// <exception cref="NotFoundException">Thrown when no configuration observation items are found for the given name.</exception>
|
||||
/// <!-- aidoc:v1 sig=9b9901d body=5a60f64 -->
|
||||
public async Task<IEnumerable<ConfigObservation>?> GetConfigObservationItem(string name)
|
||||
{
|
||||
var configObservationItems = await _configObservationRepository.FindAllByName(name);
|
||||
@@ -448,6 +466,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="originalName">The original name of the configuration observation item.</param>
|
||||
/// <returns>The matching <see cref="ConfigObservation"/> item.</returns>
|
||||
/// <exception cref="NotFoundException">Thrown when no matching configuration observation item is found.</exception>
|
||||
/// <!-- aidoc:v1 sig=3639116 body=123e8de -->
|
||||
public async Task<ConfigObservation?> GetSingleConfigObservationItem(string? code, string? codingSystem,
|
||||
string? name, string? originalName)
|
||||
{
|
||||
@@ -466,6 +485,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="configObservationItem">The configuration observation item to delete; its identifier is used to locate the existing record.</param>
|
||||
/// <returns>A task that resolves to <c>true</c> when the item is successfully deleted.</returns>
|
||||
/// <exception cref="ConflictException">Thrown when no configuration observation is found with the specified identifier, or when the underlying delete operation fails.</exception>
|
||||
/// <!-- aidoc:v1 sig=ec35183 body=8a9a0b4 -->
|
||||
public async Task<bool> DeleteSingleConfigObservationItem(ConfigObservation configObservationItem)
|
||||
{
|
||||
var configObservation = await _configObservationRepository.FindById(configObservationItem.Id) ??
|
||||
@@ -489,6 +509,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="name">The name used to filter configuration observation items.</param>
|
||||
/// <returns>A collection of <see cref="ConfigObservation"/> items matching the specified name.</returns>
|
||||
/// <!-- aidoc:v1 sig=6809b70 body=c80c2e5 -->
|
||||
public async Task<IEnumerable<ConfigObservation>> GetConfigObservationItemsByName(string name)
|
||||
{
|
||||
return await _configObservationRepository.FindAllByName(name);
|
||||
@@ -500,6 +521,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="configObservation">The configuration observation entity to persist.</param>
|
||||
/// <returns>The created <see cref="ConfigObservation"/> if the operation succeeds.</returns>
|
||||
/// <exception cref="BadRequestException">Thrown when a configuration observation with the same identifier already exists.</exception>
|
||||
/// <!-- aidoc:v1 sig=d966188 body=7d8c724 -->
|
||||
public async Task<ConfigObservation?> CreateConfig(ConfigObservation configObservation)
|
||||
{
|
||||
|
||||
@@ -520,6 +542,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="itemName">The name of the configuration item to remove.</param>
|
||||
/// <returns>The removed <see cref="ConfigObservation"/>, or <c>null</c> if the repository did not return a result.</returns>
|
||||
/// <exception cref="ConflictException">Thrown when no configuration item is found with the specified name.</exception>
|
||||
/// <!-- aidoc:v1 sig=f100c88 body=ec848a3 -->
|
||||
public async Task<ConfigObservation?> RemoveConfigItem(string itemName)
|
||||
{
|
||||
var configObservation = await GetConfigByName(itemName) ??
|
||||
@@ -543,6 +566,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="configObservationId">The unique identifier of the configuration observation to retrieve.</param>
|
||||
/// <returns>The configuration observation obtained from cache or repository, or a new empty instance when no matching record exists.</returns>
|
||||
/// <!-- aidoc:v1 sig=f3c60d4 body=645b284 -->
|
||||
public async Task<ConfigObservation?> GetConfig(ObjectId configObservationId)
|
||||
{
|
||||
RefreshCachedConfigObservations();
|
||||
@@ -570,6 +594,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="name">The case-insensitive name of the configuration observation to look up.</param>
|
||||
/// <returns>The matching <see cref="ConfigObservation"/>, or <c>null</c> if not found or the name is invalid.</returns>
|
||||
/// <!-- aidoc:v1 sig=b4fcdb3 body=2875d2c -->
|
||||
public async Task<ConfigObservation?> GetConfigByName(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name)) return null;
|
||||
@@ -602,6 +627,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// Removes expired entries from the cached configuration observations when a refresh timeout is configured,
|
||||
/// performing an early return if no refresh timeout is set.
|
||||
/// </summary>
|
||||
/// <!-- aidoc:v1 sig=1aa90f3 body=0a408f4 -->
|
||||
private void RefreshCachedConfigObservations()
|
||||
{
|
||||
if (!_refreshTimeout.HasValue) return;
|
||||
@@ -620,6 +646,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// </summary>
|
||||
/// <param name="confItem">The configuration observation to process. Its retention policy and retention policy value are updated in place.</param>
|
||||
/// <returns>A task containing the processed <see cref="ConfigObservation"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=d6edc85 body=6ba1090 -->
|
||||
private Task<ConfigObservation> Process(ConfigObservation confItem)
|
||||
{
|
||||
confItem.RetentionPolicy ??= _defaultRetentionPolicy;
|
||||
@@ -641,6 +668,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// If no refresh timeout is set, the method returns without performing any cleanup.
|
||||
/// Any exceptions encountered during the cleanup are caught and logged.
|
||||
/// </summary>
|
||||
/// <!-- aidoc:v1 sig=d3e4c66 body=bb82f36 -->
|
||||
private void RefreshCachedConfigObservationKeys()
|
||||
{
|
||||
try
|
||||
@@ -670,6 +698,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <param name="obs">The observation instance to enrich with configuration values. Modified in place.</param>
|
||||
/// <param name="conf">The configuration observation providing thresholds, colors, expiration, and other settings to apply.</param>
|
||||
/// <returns>The mapped observation, returned as-is when the observation's coding system is configured to skip status calculation.</returns>
|
||||
/// <!-- aidoc:v1 sig=4cafe53 body=3ca4d27 -->
|
||||
private async Task<T?> MapConf<T>(T obs, ConfigObservation conf) where T : BasePatientObservation
|
||||
{
|
||||
_logger.LogTrace("Mapping observation: {obs}", obs);
|
||||
@@ -819,6 +848,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <remarks>
|
||||
/// This type is intended to be used internally to store and reuse configuration observation results.
|
||||
/// </remarks>
|
||||
/// <!-- aidoc:v1 sig=9f92750 -->
|
||||
private class ConfigObservationCached
|
||||
{
|
||||
public DateTime NextRefresh { get; set; }
|
||||
@@ -828,6 +858,7 @@ public class ConfigObservationService : IConfigObservationService
|
||||
/// <summary>
|
||||
/// Represents a private cache entry for configuration observation keys, used to store and retrieve previously computed key values associated with configuration observations.
|
||||
/// </summary>
|
||||
/// <!-- aidoc:v1 sig=280cb2a -->
|
||||
private class ConfigObservationKeyCached
|
||||
{
|
||||
public DateTime NextRefresh { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user