docs: apply curated AI doc review updates for 1.0.2

Documentation branch: docs/rc-1.0.2
Technical branch: release/rc-1.0.2

Scope:
- Technical changed files: 13
- Technical changed C# files: 2
- Curated review markers: 33
- Kept review markers before apply: 32
- Removed false positives during curation: 1

Applied review files:
- adas-core.Infrastructure/Repositories/MasterListRepository.cs

Generated by n8n IEC 62304 documentation workflow.
This commit is contained in:
n8n IEC 62304 Bot
2026-06-28 22:59:38 +02:00
parent d51271effd
commit 052918f601
2 changed files with 82 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
@@ -76,6 +79,7 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// </summary>
/// <param name="entity">The entity to insert.</param>
/// <exception cref="Exception">Throws and re-throws exceptions after logging.</exception>
/// <!-- aidoc:v1 sig=c7a7ad8 body=26b3581 -->
public override async Task InsertOneAsync(T entity)
{
try
@@ -94,6 +98,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 +118,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 states 'Updates an existing' entity, but the ReplaceOptions { IsUpsert = true } means the entity will be inserted if it does not already exist, so the 'existing' qualifier is contradicted by the code's actual behavior." -->
public async Task Update(T entity)
{
try
@@ -133,6 +140,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 +174,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 (returns Task<T?>) and works on any entity type T, not specifically a 'master list entity'." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documentation says it returns 'The MasterList entity' but the method actually returns Task<T?>, a generic type." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "Documents <exception cref=\"Exception\"> but the catch block swallows all exceptions and never rethrows, so the method never throws." -->
public async Task<T?> FindById(ObjectId id)
{
try
@@ -197,6 +211,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 catches all exceptions internally (try/catch) and never throws; documenting <exception cref=\"Exception\"> is misleading. Callers will not receive any exception to handle." -->
public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId, LocaleEnum locale)
{
try
@@ -342,6 +358,8 @@ 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-review:v1 severity=medium kind=extra_exception
/// "The method contains a catch-all for Exception and never lets it propagate to callers, so documenting <exception cref=\"Exception\"> is misleading; the tag should be removed since no exception escapes this method." -->
public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId)
{
try
@@ -374,6 +392,10 @@ 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-review:v1 severity=high kind=extra_exception
/// "The <exception cref=\"Exception\"> tag is misleading: the catch block handles all exceptions internally and the method returns null, so no Exception is ever thrown to callers. Listing Exception implies callers must handle it, which they cannot." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documentation says 'The MasterList entity' but the method signature is generic Task<T?>, so the returned type is T, not necessarily a MasterList." -->
public async Task<T?> FindById(ObjectId id, LocaleEnum? locale)
{
try
@@ -556,6 +578,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_exception
/// "The <exception> tag documents Exception being thrown, but the method catches all exceptions internally and returns null instead of letting any exception propagate to the caller." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "The summary specifies a 'master list entity', but the method is generic (T) and could operate on any type with a Name property; the documentation should not assume a specific type." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "The <returns> tag describes a MasterList entity, but the method returns Task<T?> where T is a generic type parameter, not necessarily MasterList." -->
public async Task<T?> FindByName(string name)
{
try
@@ -584,6 +612,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 +623,10 @@ 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_summary
/// "Summary claims the method 'retrieves paginated master lists', but the code only builds filters/sort and returns an IFindFluent without any pagination logic (no Skip/Limit)." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Returns tag specifies 'MasterList results', but the method is generic and returns IFindFluent<T, T>, not specifically MasterList." -->
public IFindFluent<T, T> GetPaginatedMasterList(PaginationFilter filter)
{
var filterBuilder = Builders<T>.Filter;
@@ -621,6 +654,8 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
/// <param name="filter">The pagination and filtering parameters.</param>
/// <param name="listId">The ObjectId of the master list.</param>
/// <returns>A list of filtered OptionList items.</returns>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Summary and method name claim 'paginated' results, but the code applies only text filtering with no skip/take/page logic — the PaginationFilter's pagination fields are unused." -->
public async Task<List<OptionList>> GetPaginatedOptions(PaginationFilter filter, ObjectId listId)
{
//TODO: LOCALE
@@ -646,6 +681,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=medium kind=extra_exception
/// "The method catches all exceptions internally and returns null; it never throws an Exception to the caller, so documenting <exception cref=\"Exception\"> is misleading." -->
public async Task<OptionList?> AddOptionToMasterList(ObjectId id, FilterOptionListElement opt)
{
var exist = await GetMasterListByIdAndSearchOptions(id, opt);
@@ -689,6 +726,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
/// "Summary says 'Retrieves all master list entities' but the method is generic over T and operates on the configured Collection, not specifically MasterList entities." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Returns tag says 'An enumerable of all MasterList entities' but the method returns Task<IEnumerable<T>>, where T is a generic type parameter." -->
/// <!-- aidoc-review:v1 severity=high kind=extra_exception
/// "<exception cref=\"Exception\"> implies the method may throw Exception, but the catch block swallows all exceptions and returns an empty list; the method does not throw Exception." -->
public async Task<IEnumerable<T>> GetAll()
{
try
@@ -708,6 +751,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=medium kind=extra_exception
/// "The method catches all exceptions internally (try/catch around the entire body) and returns an empty list; it never throws Exception to the caller, so the <exception cref=\"Exception\"> tag is misleading." -->
public async Task<IEnumerable<MasterListDto>> GetAllWithoutOptions()
{
try
@@ -736,6 +781,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=medium kind=wrong_exception
/// "The method catches all Exception internally and returns 0, so it never throws Exception to callers. The <exception cref=\"Exception\"> tag misleads readers into expecting exceptions to propagate." -->
public async Task<int> Count()
{
try
@@ -758,6 +805,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 catches all Exception instances and logs them without rethrowing, so no Exception is propagated to the caller; documenting <exception cref=\"Exception\"> is misleading." -->
public async Task<List<OptionList>> GetMasterListByIdAndSearchOptions(ObjectId id, FilterOptionListElement? filters)
{
try
@@ -973,6 +1022,8 @@ 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-review:v1 severity=medium kind=extra_exception
/// "The method catches all exceptions internally and returns null; it does not propagate any exception to callers, so the <exception cref=\"Exception\"/> tag is misleading." -->
public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt, LocaleEnum locale)
{
// 1. Evitar duplicados
@@ -1073,6 +1124,8 @@ 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-review:v1 severity=medium kind=extra_exception
/// "The <exception cref=\"Exception\"> tag is misleading because the method catches Exception rather than throwing it. The described behavior (log and return null) matches the catch block, but this is not an exception thrown by the method." -->
public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt)
{
var master = await FindById(id);
@@ -1108,6 +1161,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 +1186,10 @@ 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 method catches all exceptions internally and never throws them, so documenting <exception cref=\"Exception\"> is misleading" -->
/// <!-- aidoc-review:v1 severity=medium kind=wrong_summary
/// "Summary says 'metadata details' but the method updates option details (CanAddElement, OptionListDetails)" -->
public async Task<UpdateMasterListDetailsDto?> UpdateOptionDetailsToMasterList(ObjectId id,
UpdateMasterListDetailsDto opt)
{
@@ -1167,6 +1225,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=medium kind=extra_exception
/// "The method catches all exceptions internally and never rethrows them, so <exception cref=\"Exception\"> is misleading; callers cannot actually receive an exception from this method." -->
public async Task<bool> UpdateMasterListName(ObjectId id, string name)
{
var filter = Builders<T>.Filter.And(
@@ -1193,6 +1253,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=extra_exception
/// "The method catches all exceptions internally and returns false; it never throws an Exception, so the <exception cref=\"Exception\"> tag is incorrect." -->
public async Task<bool> UpdateMasterListDescription(ObjectId id, string description)
{
var filter = Builders<T>.Filter.And(
@@ -1219,6 +1281,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=high kind=extra_exception
/// "The method catches all exceptions in a try/catch and returns false; it does not throw Exception, so the <exception> tag is misleading." -->
public async Task<bool> RemoveMasterListOption(ObjectId id, OptionList oldOpt)
{
var filter = Builders<T>.Filter.Eq("_id", id);
@@ -1250,6 +1314,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 claims 'text indexes' are created, but the code uses Builders<T>.IndexKeys.Ascending(), which creates ascending (non-text) indexes." -->
public override async Task CreateIndexes()
{
if (typeof(T) == typeof(DiagnosisList))
@@ -1275,6 +1341,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 +1354,8 @@ 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-review:v1 severity=medium kind=extra_exception
/// "The method catches all exceptions internally (catch (Exception ex)) and never throws to the caller; the <exception cref=\"Exception\"> tag is misleading and should be removed. The catch-block description belongs in the summary or remarks instead." -->
private async Task<List<OptionList>> GetOptionsByTextSearch(string? textSearch, ObjectId? id = null)
{
try
@@ -1364,6 +1433,7 @@ 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:v1 sig=704d715 body=2a35652 -->
private IFindFluent<T, T> CreateFindFluent(List<FilterDefinition<T>> filters, SortDefinition<T> sort)
{
var combinedFilter = filters.Any()
@@ -1379,6 +1449,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=stale_summary
/// "Summary says items are created for all locales except 'the specified default', but the code also always skips LocaleEnum.Default in addition to the localeList parameter; only one exclusion is documented when two occur." -->
private Locale GetNewItemLocale(LocaleEnum localeList, string opt)
{
var newLocale = new Locale();
@@ -1418,6 +1490,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 +1532,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=medium kind=extra_exception
/// "The <exception cref=\"Exception\"> tag documents an exception that is never thrown to the caller: the method catches all exceptions internally, logs them, and returns an empty list. The descriptive text 'Logs errors and returns empty list on failure' is accurate but should not be tagged as an exception." -->
private async Task<List<OptionList>> GetMasterListByIdAndTextSearch(
ObjectId id, string newOptName, LocaleEnum locale)
{