docs(iec62304): [REL-1.0.2] validate and curate XML doc review markers

This commit is contained in:
n8n IEC 62304 Bot
2026-07-06 17:00:55 +02:00
parent 255e6f6250
commit 481d768ebd
2 changed files with 83 additions and 0 deletions
@@ -20,6 +20,7 @@ namespace adas_core.Infrastructure.Repositories;
/// options lists, diagnoses, allergies, procedures, treatments, and other reference data.
/// </summary>
/// <typeparam name="T">The type of MasterList entity to manage.</typeparam>
/// <!-- aidoc:v1 sig=f958de2 -->
public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository<T> where T : MasterList
{
private readonly ApiSettings _apiSettings;
@@ -30,6 +31,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="apiSettings">API settings containing collection names configuration.</param>
/// <param name="database">The MongoDB database instance.</param>
/// <exception cref="ArgumentNullException">Thrown when apiSettings is null.</exception>
/// <!-- aidoc:v1 sig=800d538 body=d2b18a3 -->
public MasterListRepository(IOptions<ApiSettings> apiSettings, IMongoDatabase database) : base(database)
{
if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings));
@@ -41,6 +43,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// Maps different MasterList subtypes to their corresponding MongoDB collection names.
/// </summary>
/// <returns>The collection name for the current MasterList type.</returns>
/// <!-- aidoc:v1 sig=94e22ff body=64e6c55 -->
public override string GetCollectionName()
{
return typeof(T) switch
@@ -94,6 +97,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <param name="id">The ObjectId of the entity to delete.</param>
/// <exception cref="Exception">Throws and re-throws exceptions after logging.</exception>
/// <!-- aidoc:v1 sig=3de1ad6 body=fe0ba8c -->
public async Task Delete(ObjectId id)
{
try
@@ -113,6 +117,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <param name="entity">The entity with updated values.</param>
/// <exception cref="Exception">Throws and re-throws exceptions after logging.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=wrong_summary
/// "Summary says 'Updates an existing' entity, but the code uses IsUpsert = true, so the method can also insert a new entity when one does not exist." -->
public async Task Update(T entity)
{
try
@@ -133,6 +139,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="id">The ObjectId of the master list.</param>
/// <param name="newOpt">The OptionList with updated values.</param>
/// <returns>The updated OptionList if found; otherwise, null.</returns>
/// <!-- aidoc:v1 sig=64ca4dd body=a7714e6 -->
public async Task<OptionList?> UpdateFullMasterListOption(ObjectId id, OptionList newOpt)
{
var filter = Builders<T>.Filter.Where(o => o.Id == id && o.Options.Any(opt => opt.Id == newOpt.Id)
@@ -166,6 +173,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="id">The ObjectId of the entity to retrieve.</param>
/// <returns>The MasterList entity if found; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Method is generic (FindById<T>) and not specific to a 'master list entity'; summary incorrectly scopes it to master list." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documentation says 'The MasterList entity' but the method's return type is the generic T?, not a MasterList." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "Documents <exception cref=\"Exception\">, but the method catches all exceptions internally and never propagates them to the caller." -->
public async Task<T?> FindById(ObjectId id)
{
try
@@ -197,6 +210,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="locale">The locale for translation.</param>
/// <returns>The OptionList with translated fields if found; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The method wraps its entire body in a try/catch that catches Exception, logs it, and returns null; it never propagates Exception to the caller, so the <exception cref=\"Exception\"/> tag is misleading. The behavior described (log and return null) belongs in the <remarks> or summary, not as a thrown exception." -->
public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId, LocaleEnum locale)
{
try
@@ -342,6 +357,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="optionId">The ObjectId of the option to retrieve.</param>
/// <returns>The OptionList if found; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=ccc34cb body=71837cc -->
public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId)
{
try
@@ -374,6 +390,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="locale">Optional locale for translated option names.</param>
/// <returns>The MasterList entity with translated options if found; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=cb4a658 body=f2e88d8 -->
public async Task<T?> FindById(ObjectId id, LocaleEnum? locale)
{
try
@@ -556,6 +573,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="name">The name of the master list to retrieve.</param>
/// <returns>The MasterList entity if found; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "The method returns Task<T?> (generic), not MasterList; the return type description should reference T, not MasterList." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Summary says 'Finds a master list entity' but the method is generic (T) and is not specific to master lists." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The method catches all exceptions internally and returns null; it does not propagate any exception, so the <exception> tag is misleading." -->
public async Task<T?> FindByName(string name)
{
try
@@ -584,6 +607,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="id">The ObjectId of the master list.</param>
/// <param name="textSearch">Optional text to search within options.</param>
/// <returns>A list of matching OptionList items.</returns>
/// <!-- aidoc:v1 sig=569d223 body=bb7f2c6 -->
public async Task<List<OptionList>> GetMasterListByIdAndTextSearchContaining(ObjectId id, string? textSearch)
{
return await GetOptionsByTextSearch(textSearch, id);
@@ -594,6 +618,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <param name="filter">The pagination and filtering parameters.</param>
/// <returns>A fluent queryable for MasterList results.</returns>
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documentation states the method returns 'A fluent queryable for MasterList results', but the method returns IFindFluent<T, T> where T is a generic type parameter, not specifically MasterList." -->
public IFindFluent<T, T> GetPaginatedMasterList(PaginationFilter filter)
{
var filterBuilder = Builders<T>.Filter;
@@ -646,6 +672,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="opt">The option element to add.</param>
/// <returns>The newly created OptionList if successful; otherwise, null if duplicate exists.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "<exception cref=\"Exception\"> documents an exception that is caught and handled inside the method (try/catch returns null) rather than thrown out to the caller." -->
public async Task<OptionList?> AddOptionToMasterList(ObjectId id, FilterOptionListElement opt)
{
var exist = await GetMasterListByIdAndSearchOptions(id, opt);
@@ -689,6 +717,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <returns>An enumerable of all MasterList entities.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Method is generic (IEnumerable<T>), not specific to 'master list entities'; the name 'master list' does not appear in the code." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documents 'An enumerable of all MasterList entities' but the method is generic and returns IEnumerable<T>, not a concrete MasterList type." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "Documents <exception cref='Exception'> but the method catches all exceptions internally and returns an empty list; it does not throw Exception." -->
public async Task<IEnumerable<T>> GetAll()
{
try
@@ -708,6 +742,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <returns>An enumerable of MasterListDto containing id, name, description, listType, and options count.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The method catches all exceptions in a try/catch and returns an empty list without rethrowing, so it does not throw Exception. The <exception> tag misleads readers into expecting an exception to propagate." -->
public async Task<IEnumerable<MasterListDto>> GetAllWithoutOptions()
{
try
@@ -736,6 +772,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <returns>The total count of entities.</returns>
/// <exception cref="Exception">Logs errors and returns 0 on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The method catches all exceptions and returns 0, so it never throws Exception. The <exception cref=\"Exception\"> tag misleads readers into thinking the method can throw." -->
public async Task<int> Count()
{
try
@@ -758,6 +796,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="filters">The filter criteria including text, name, description, and optionType.</param>
/// <returns>A list of matching OptionList items ordered by name.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The method has a catch (Exception ex) block that logs and returns an empty list; it does not propagate any exception to callers, making the <exception cref='Exception'> tag misleading." -->
public async Task<List<OptionList>> GetMasterListByIdAndSearchOptions(ObjectId id, FilterOptionListElement? filters)
{
try
@@ -973,6 +1013,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="locale">The locale for translation updates.</param>
/// <returns>The updated OptionList if successful; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=e771f23 body=5520a4a -->
public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt, LocaleEnum locale)
{
// 1. Evitar duplicados
@@ -1073,6 +1114,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="newOpt">The OptionList with updated values.</param>
/// <returns>The updated OptionList if successful; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=6def54c body=9554543 -->
public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt)
{
var master = await FindById(id);
@@ -1108,6 +1150,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="id">The ObjectId of the master list.</param>
/// <param name="deleteOptId">The ObjectId of the option to delete.</param>
/// <returns>True if the option was deleted; otherwise, false.</returns>
/// <!-- aidoc:v1 sig=e663f16 body=75627bc -->
public async Task<bool> DeleteMasterListOption(ObjectId id, ObjectId deleteOptId)
{
// Define el filtro para encontrar el documento por su _id
@@ -1132,6 +1175,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="opt">The UpdateMasterListDetailsDto with updated values.</param>
/// <returns>The updated UpdateMasterListDetailsDto if successful; otherwise, null.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The <exception cref=\"Exception\"> tag suggests the method may throw Exception, but the body catches all exceptions internally, logs them, and returns null without rethrowing." -->
public async Task<UpdateMasterListDetailsDto?> UpdateOptionDetailsToMasterList(ObjectId id,
UpdateMasterListDetailsDto opt)
{
@@ -1167,6 +1212,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="name">The new name.</param>
/// <returns>True if the update was successful; otherwise, false.</returns>
/// <exception cref="Exception">Logs errors and returns false on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The <exception cref=\"Exception\"> tag documents an exception that is never thrown. The method's try/catch block catches all Exception types and returns false, so callers do not need to handle any exception thrown by this method." -->
public async Task<bool> UpdateMasterListName(ObjectId id, string name)
{
var filter = Builders<T>.Filter.And(
@@ -1193,6 +1240,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="description">The new description.</param>
/// <returns>True if the update was successful; otherwise, false.</returns>
/// <exception cref="Exception">Logs errors and returns false on failure.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The method catches all exceptions and returns false rather than throwing them, so an <exception> tag documenting that exceptions are thrown is misleading." -->
public async Task<bool> UpdateMasterListDescription(ObjectId id, string description)
{
var filter = Builders<T>.Filter.And(
@@ -1219,6 +1268,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="oldOpt">The OptionList to remove.</param>
/// <returns>True if the option was removed; otherwise, false.</returns>
/// <exception cref="Exception">Logs errors and returns false on failure.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The method catches all exceptions internally and returns false rather than propagating them, so an <exception> tag is misleading." -->
public async Task<bool> RemoveMasterListOption(ObjectId id, OptionList oldOpt)
{
var filter = Builders<T>.Filter.Eq("_id", id);
@@ -1250,6 +1301,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// Creates necessary indexes for the MasterList collection.
/// Currently creates text indexes for DiagnosisList on options.name, options.description, and options._id.
/// </summary>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Documentation states the method 'creates text indexes', but the code uses Builders<T>.IndexKeys.Ascending(...) to create ascending indexes, not text indexes. The language options (LanguageOverride/DefaultLanguage) are configured, but no Text index keys are used." -->
public override async Task CreateIndexes()
{
if (typeof(T) == typeof(DiagnosisList))
@@ -1275,6 +1328,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <param name="textSearch">Optional text to search within options.</param>
/// <returns>A list of matching OptionList items.</returns>
/// <!-- aidoc:v1 sig=484b092 body=48e3496 -->
public async Task<List<OptionList>> GetMasterListByTextSearch(string? textSearch)
{
return await GetOptionsByTextSearch(textSearch);
@@ -1287,6 +1341,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="id">Optional master list ObjectId to filter results.</param>
/// <returns>A list of matching OptionList items ordered by name.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc:v1 sig=6ebeac8 body=1d7bbb7 -->
private async Task<List<OptionList>> GetOptionsByTextSearch(string? textSearch, ObjectId? id = null)
{
try
@@ -1364,6 +1419,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="filters">List of filter definitions to apply.</param>
/// <param name="sort">Sort definition for the query results.</param>
/// <returns>A fluent queryable for T results.</returns>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "The method does not perform pagination (no Skip/Limit applied). It only combines filters and applies a sort, so 'paginated results' in the summary is incorrect." -->
private IFindFluent<T, T> CreateFindFluent(List<FilterDefinition<T>> filters, SortDefinition<T> sort)
{
var combinedFilter = filters.Any()
@@ -1379,6 +1436,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="localeList">The default locale to exclude from translations.</param>
/// <param name="opt">The option name to use as default translation.</param>
/// <returns>A Locale object with translations for all other locales.</returns>
/// <!-- aidoc-review:v1 severity=medium kind=wrong_summary
/// "The summary says entries are created for 'all locales except the specified default', but the code also always excludes LocaleEnum.Default (hardcoded skip) in addition to the localeList parameter, which is not mentioned." -->
private Locale GetNewItemLocale(LocaleEnum localeList, string opt)
{
var newLocale = new Locale();
@@ -1418,6 +1477,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <param name="input">The input string to build the pattern from.</param>
/// <returns>A regex-compatible pattern string.</returns>
/// <!-- aidoc:v1 sig=2992c00 body=ae88daf -->
private static string BuildRegexPattern(string input)
{
var regexPattern = new StringBuilder();
@@ -1459,6 +1519,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="locale">The locale for translation.</param>
/// <returns>A list of matching OptionList items ordered by name.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc-review:v1 severity=low kind=extra_exception
/// "The method catches all exceptions internally and returns an empty list; the <exception cref=\"Exception\"> tag is misleading because the method does not actually throw any exception to the caller." -->
private async Task<List<OptionList>> GetMasterListByIdAndTextSearch(
ObjectId id, string newOptName, LocaleEnum locale)
{