docs(iec62304): [REL-1.0.2] apply curated XML doc review updates

This commit is contained in:
n8n IEC 62304 Bot
2026-07-06 19:14:03 +02:00
parent c9446ed5d7
commit 3c2d522c45
2 changed files with 50 additions and 75 deletions
@@ -168,13 +168,14 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Asynchronously finds an entity by its <paramref name="id"/>, returning the first matching document with its "options" array limited to 100 elements via projection. If no document matches or an exception is thrown, the error is logged and <c>null</c> is returned. /// Asynchronously retrieves an entity of type <typeparamref name="T"/> matching the supplied <see cref="ObjectId"/>,
/// applying a projection that limits the <c>options</c> field to 100 elements.
/// Exceptions raised during the lookup are logged and surfaced as a <c>null</c> result.
/// </summary> /// </summary>
/// <param name="id">The <see cref="ObjectId"/> used to build the equality filter against the entity's identifier.</param> /// <typeparam name="T">The document type stored in the collection, expected to expose an <see cref="ObjectId"/> <c>Id</c> property.</typeparam>
/// <returns>A <see cref="Task{T}"/> that yields the matching entity, or <c>null</c> when no document is found or the operation fails.</returns> /// <param name="id">The <see cref="ObjectId"/> that uniquely identifies the entity to find.</param>
/// <returns>A <see cref="Task{T}"/> containing the matching entity, or <c>null</c> when no document is found or the operation fails.</returns>
/// <!-- aidoc:v1 sig=81ac96a body=1519944 --> /// <!-- aidoc:v1 sig=81ac96a body=1519944 -->
/// <!-- aidoc-review:v1 severity=low kind=wrong_summary
/// "The summary implies that 'the error is logged' in both the no-match and exception cases, but the code only logs in the catch block; FirstOrDefaultAsync returning null is not logged." -->
public async Task<T?> FindById(ObjectId id) public async Task<T?> FindById(ObjectId id)
{ {
try try
@@ -344,15 +345,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Finds a specific option within a master list by master and option IDs without locale translation. /// Retrieves a single <see cref="OptionList"/> entry from the master document that matches the given <paramref name="masterId"/> and <paramref name="optionId"/>. Returns <c>null</c> when no matching document is found, no option matches, or when the operation fails.
/// </summary> /// </summary>
/// <param name="masterId">The ObjectId of the master list.</param> /// <param name="masterId">The <see cref="MongoDB.Bson.ObjectId"/> of the master document that owns the options array.</param>
/// <param name="optionId">The ObjectId of the option to retrieve.</param> /// <param name="optionId">The <see cref="MongoDB.Bson.ObjectId"/> of the specific option to locate within the master's options array.</param>
/// <returns>The OptionList if found; otherwise, null.</returns> /// <returns>A <see cref="Task{TResult}"/> that resolves to the matching <see cref="OptionList"/>, or <c>null</c> if no match is found or an error occurs.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=ccc34cb body=71837cc --> /// <!-- aidoc:v1 sig=ccc34cb body=71837cc -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The method catches all exceptions and returns null rather than throwing; the <exception cref=\"Exception\"> tag is misleading because the method does not propagate any exception to its caller." -->
public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId) public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId)
{ {
try try
@@ -603,14 +601,11 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Builds a sorted master-list query for documents of type <typeparamref name="T"/>, returning all documents ordered ascending by the <c>name</c> field, or only those whose <c>Name</c> matches <paramref name="filter"/>'s search text via a case-insensitive regex (with special characters escaped) when provided. /// Retrieves a paginated master list of <typeparamref name="T"/> items sorted by name in ascending order, applying an optional case-insensitive regex filter on the Name property when a text filter is provided. If no filter request is specified, returns all items without additional filters.
/// If <paramref name="filter"/> is null, its <c>FilteredRequest</c> is null, or <c>FilteredRequest.Text</c> is null or empty, no additional filter is applied and the unfiltered, sorted result is returned.
/// </summary> /// </summary>
/// <param name="filter">The <see cref="PaginationFilter"/> containing the optional <c>FilteredRequest.Text</c> used to match the <c>Name</c> field.</param> /// <param name="filter">The <see cref="PaginationFilter"/> containing the pagination and optional text filtering criteria.</param>
/// <returns>An <see cref="IFindFluent{TDocument, TProjection}"/> representing the sorted, filtered query against the collection of <typeparamref name="T"/>.</returns> /// <returns>An <see cref="IFindFluent{T, T}"/> representing the queryable collection of matching items, sorted by name.</returns>
/// <!-- aidoc:v1 sig=bbb39c7 body=f42ebaa --> /// <!-- aidoc:v1 sig=bbb39c7 body=f42ebaa -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "The summary claims that if 'filter' is null no additional filter is applied and the unfiltered, sorted result is returned, but the code accesses 'filter.FilteredRequest' without a null check and would throw a NullReferenceException when 'filter' is null." -->
public IFindFluent<T, T> GetPaginatedMasterList(PaginationFilter filter) public IFindFluent<T, T> GetPaginatedMasterList(PaginationFilter filter)
{ {
var filterBuilder = Builders<T>.Filter; var filterBuilder = Builders<T>.Filter;
@@ -774,18 +769,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Searches for options within a master list using multiple filter criteria. /// Retrieves a filtered, locale-aware list of <see cref="OptionList"/> options from the master list document identified by <paramref name="id"/>, applying the optional search criteria supplied in <paramref name="filters"/>. When <paramref name="filters"/> is null or an error occurs during execution, an empty list is returned; translations are resolved per option for the requested locale, falling back to the original name and description when no localized value is available.
/// Uses MongoDB aggregation pipeline to apply filters and locale translations.
/// </summary> /// </summary>
/// <param name="id">The ObjectId of the master list.</param> /// <param name="id">The <see cref="ObjectId"/> of the master list document to query.</param>
/// <param name="filters">The filter criteria including text, name, description, and optionType.</param> /// <param name="filters">The optional <see cref="FilterOptionListElement"/> containing the search criteria (option type, text, name, description, and locale) used to filter the resulting options.</param>
/// <returns>A list of matching OptionList items ordered by name.</returns> /// <returns>A <see cref="Task{List{OptionList}}"/> containing the matching options ordered by name, or an empty list when no options match, the filters are null, or the operation fails.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc:v1 sig=f6ee5be body=17d6a96 --> /// <!-- aidoc:v1 sig=f6ee5be body=17d6a96 -->
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The method catches every Exception in its body and returns an empty list; it does not throw Exception to callers, so the <exception> tag is misleading." -->
/// <!-- aidoc-review:v1 severity=medium kind=missing_param
/// "filters.Locale is used in the aggregation pipeline to drive locale-based translations but is not mentioned in the <param name=\"filters\"> description." -->
public async Task<List<OptionList>> GetMasterListByIdAndSearchOptions(ObjectId id, FilterOptionListElement? filters) public async Task<List<OptionList>> GetMasterListByIdAndSearchOptions(ObjectId id, FilterOptionListElement? filters)
{ {
try try
@@ -994,16 +983,13 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Updates a specific option within a master list with locale-aware field updates. /// Updates an option of the master list identified by <paramref name="id"/>, applying locale-aware handling so that <see cref="OptionList.Name"/> is written to the default field when <paramref name="locale"/> equals the master default locale and to the per-locale translation entry otherwise, and persisting the remaining presentation fields (icons, colors, description, dates, <see cref="OptionList.OptionType"/>) only when they are supplied and, where applicable, allowed by the master configuration. Returns the existing duplicate when a name collision is found, the updated <see cref="OptionList"/> on success, or null when no field qualifies, no document is modified, or the operation throws.
/// </summary> /// </summary>
/// <param name="id">The ObjectId of the master list.</param> /// <param name="id">Identifier of the master list that owns the option being updated.</param>
/// <param name="newOpt">The OptionList with updated values.</param> /// <param name="newOpt">Option carrying the new values; only non-null members are applied, and <see cref="OptionList.Name"/> and <see cref="OptionList.OptionType"/> are additionally gated by the required flags defined on the master configuration.</param>
/// <param name="locale">The locale for translation updates.</param> /// <param name="locale">Target <see cref="LocaleEnum"/> used to decide whether to update the default <see cref="OptionList.Name"/> field or the locale-specific translation entry.</param>
/// <returns>The updated OptionList if successful; otherwise, null.</returns> /// <returns>A <see cref="Task{OptionList}"/> resolving to the existing or updated <see cref="OptionList"/>, or null when no update is performed or the caught error is logged.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=e771f23 body=5520a4a --> /// <!-- aidoc:v1 sig=e771f23 body=5520a4a -->
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The method catches Exception and does not re-throw it; the <exception> tag documents caught-and-handled behavior as if it were a thrown exception, which is non-standard and misleading." -->
public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt, LocaleEnum locale) public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt, LocaleEnum locale)
{ {
// 1. Evitar duplicados // 1. Evitar duplicados
@@ -1098,15 +1084,13 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Updates a specific option within a master list with full replacement. /// Updates an option within the master list identified by <paramref name="id"/>, replacing it with <paramref name="newOpt"/>.
/// Returns <see langword="null"/> if the master list cannot be found, if no document is modified, or if an exception occurs during the update (which is logged).
/// </summary> /// </summary>
/// <param name="id">The ObjectId of the master list.</param> /// <param name="id">The identifier of the master list that contains the option to update.</param>
/// <param name="newOpt">The OptionList with updated values.</param> /// <param name="newOpt">The new <see cref="OptionList"/> that will replace the existing option in the master list.</param>
/// <returns>The updated OptionList if successful; otherwise, null.</returns> /// <returns>The updated <see cref="OptionList"/> retrieved after a successful update, or <see langword="null"/> if the master list is missing, the update had no effect, or an error was raised.</returns>
/// <exception cref="Exception">Logs errors and returns null on failure.</exception>
/// <!-- aidoc:v1 sig=6def54c body=9554543 --> /// <!-- aidoc:v1 sig=6def54c body=9554543 -->
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "<exception cref=\"Exception\"> is documented but the method catches all exceptions internally and never rethrows them; the tag should be removed or rephrased to describe the catch behavior." -->
public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt) public async Task<OptionList?> UpdateMasterListOption(ObjectId id, OptionList newOpt)
{ {
var master = await FindById(id); var master = await FindById(id);
@@ -1324,15 +1308,14 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Searches for options within a master list using text search with accent-aware regex. /// Asynchronously retrieves a list of <see cref="OptionList"/> entries whose name or description matches the provided search text within the document identified by <paramref name="id"/>.
/// Returns an empty list when <paramref name="textSearch"/> is null, empty, or whitespace, or when an error occurs during execution.
/// Matching is performed case-insensitively using a regex pattern, and the resulting options are ordered by name.
/// </summary> /// </summary>
/// <param name="textSearch">Optional text to search within options.</param> /// <param name="textSearch">The text to search for in the option's name and description. If null, empty, or whitespace, the method returns an empty list.</param>
/// <param name="id">Optional master list ObjectId to filter results.</param> /// <param name="id">The optional <see cref="ObjectId"/> of the document whose options will be filtered. Defaults to <see langword="null"/>.</param>
/// <returns>A list of matching OptionList items ordered by name.</returns> /// <returns>A <see cref="Task"/> that yields a <see cref="List{T}"/> of <see cref="OptionList"/> matching the search criteria, ordered by name, or an empty list if no matches are found or an error occurs.</returns>
/// <exception cref="Exception">Logs errors and returns empty list on failure.</exception>
/// <!-- aidoc:v1 sig=6ebeac8 body=1d7bbb7 --> /// <!-- aidoc:v1 sig=6ebeac8 body=1d7bbb7 -->
/// <!-- aidoc-review:v1 severity=medium kind=extra_exception
/// "The method wraps the body in a try-catch that catches Exception and returns an empty list, so it never throws Exception to the caller; documenting it via <exception> is misleading." -->
private async Task<List<OptionList>> GetOptionsByTextSearch(string? textSearch, ObjectId? id = null) private async Task<List<OptionList>> GetOptionsByTextSearch(string? textSearch, ObjectId? id = null)
{ {
try try
@@ -1499,20 +1482,15 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
} }
/// <summary> /// <summary>
/// Retrieves the options of a master list document identified by <paramref name="id"/>, applying locale-aware /// Retrieves the options of a master list document identified by <paramref name="id"/>, filtering those whose resolved name equals <paramref name="newOptName"/> using the supplied <paramref name="locale"/>.
/// translation of the option name and filtering the results to those whose translated name matches /// The aggregation resolves each option's name by preferring the translation for <paramref name="locale"/> from the locale-specific items, falling back to the original name when no translation is present, and always using the original name when <paramref name="locale"/> matches the document's default locale.
/// <paramref name="newOptName"/>. When the requested <paramref name="locale"/> matches the document's default /// Matching options are returned ordered by name; an empty list is returned when the document is not found, no option matches, or an error is logged.
/// locale the original name is used; otherwise the translated name is preferred and falls back to the original
/// when no translation exists. Returns the matching options ordered by name, or an empty list when the
/// document is not found, no option matches, or an error is logged.
/// </summary> /// </summary>
/// <param name="id">The <see cref="MongoDB.Bson.ObjectId"/> of the master list document to query.</param> /// <param name="id">The <see cref="MongoDB.Bson.ObjectId"/> of the master list document to match.</param>
/// <param name="newOptName">The option name to match against the locale-resolved name of each option.</param> /// <param name="newOptName">The option name to filter by after locale resolution.</param>
/// <param name="locale">The <see cref="LocaleEnum"/> value used to select the translated name for each option.</param> /// <param name="locale">The locale used to select the translated name field.</param>
/// <returns>A <see cref="Task"/> containing a <see cref="List{Object}"/> of matching options ordered by name, or an empty list when no options match or an error occurs.</returns> /// <returns>A <see cref="Task"/> containing a <see cref="List{OptionList}"/> of matching options ordered by name, or an empty list when no matches are found or an error is logged.</returns>
/// <!-- aidoc:v1 sig=342dc63 body=21f31fc --> /// <!-- aidoc:v1 sig=342dc63 body=21f31fc -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "The <returns> tag references List{Object}, but the method actually returns Task<List<OptionList>>." -->
private async Task<List<OptionList>> GetMasterListByIdAndTextSearch( private async Task<List<OptionList>> GetMasterListByIdAndTextSearch(
ObjectId id, string newOptName, LocaleEnum locale) ObjectId id, string newOptName, LocaleEnum locale)
{ {
+10 -13
View File
@@ -167,15 +167,13 @@ public class LdapLoginService : ILoginService
=> throw new LoginServicesException("Not implemented"); => throw new LoginServicesException("Not implemented");
/// <summary> /// <summary>
/// Authenticates a user with the provided <paramref name="username"/> and <paramref name="password"/>. /// Authenticates a user with the specified <paramref name="username"/> and <paramref name="password"/> credentials.
/// </summary> /// </summary>
/// <param name="username">The username of the user attempting to authenticate.</param> /// <param name="username">The username of the user to authenticate.</param>
/// <param name="password">The password of the user attempting to authenticate.</param> /// <param name="password">The password of the user to authenticate.</param>
/// <returns>A <see cref="Task{User}"/> that represents the asynchronous authentication operation, yielding the authenticated <see cref="User"/> on success.</returns> /// <returns>A <see cref="Task{User}"/> that resolves to the authenticated <see cref="User"/>.</returns>
/// <exception cref="LoginServicesException">Thrown because the authentication operation is not yet implemented.</exception> /// <exception cref="LoginServicesException">Thrown when the method is invoked, as authentication is not implemented.</exception>
/// <!-- aidoc:v1 sig=a0b1f46 --> /// <!-- aidoc:v1 sig=a0b1f46 -->
/// <!-- aidoc-review:v1 severity=low kind=wrong_returns
/// "The returns description mentions yielding the authenticated User on success, but the method never reaches success since it always throws. Mitigated by the exception tag noting the not-implemented state." -->
public Task<User> Authenticate(string username, string password) public Task<User> Authenticate(string username, string password)
=> throw new LoginServicesException("Not implemented"); => throw new LoginServicesException("Not implemented");
@@ -190,14 +188,13 @@ public class LdapLoginService : ILoginService
=> throw new LoginServicesException("Not implemented"); => throw new LoginServicesException("Not implemented");
/// <summary> /// <summary>
/// Retrieves a <see cref="User"/> matching the supplied email address, or <see langword="null"/> when no user is found. /// Retrieves a <see cref="User"/> identified by the supplied email address.
/// The method is not implemented and always throws a <see cref="LoginServicesException"/>.
/// </summary> /// </summary>
/// <param name="email">The email address used to look up the <see cref="User"/>.</param> /// <param name="email">The email address used to look up the user.</param>
/// <returns>A <see cref="Task{T}"/> that resolves to the matching <see cref="User"/>, or <see langword="null"/> if no user exists for the given <paramref name="email"/>.</returns> /// <returns>A task that resolves to the matching <see cref="User"/>, or null if no user is found with the given email.</returns>
/// <exception cref="LoginServicesException">Thrown because the operation is not implemented.</exception> /// <exception cref="LoginServicesException">Thrown because the method is not implemented.</exception>
/// <!-- aidoc:v1 sig=ba92b09 --> /// <!-- aidoc:v1 sig=ba92b09 -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "The summary and returns describe retrieving a User (or null), but the method body unconditionally throws LoginServicesException and never performs any lookup or returns a User." -->
public Task<User?> GetByEmail(string email) public Task<User?> GetByEmail(string email)
=> throw new LoginServicesException("Not implemented"); => throw new LoginServicesException("Not implemented");