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

This commit is contained in:
n8n IEC 62304 Bot
2026-07-06 18:42:11 +02:00
parent a67a9f5443
commit 5b4dc2710b
2 changed files with 130 additions and 171 deletions
@@ -114,14 +114,11 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Updates an existing master list entity with full replacement.
/// Replaces the document matching <paramref name="entity"/>'s identifier, or inserts it as a new document when no match is found (upsert).
/// Any exception raised during the operation is logged and rethrown to the caller.
/// </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=high kind=wrong_summary
/// "Summary says 'Updates an existing' entity, but IsUpsert = true means the method will also insert the document if it does not already exist, so 'existing' is contradicted by the code." -->
/// <!-- aidoc-review:v1 severity=high kind=stale_summary
/// "The phrase 'master list entity' is not supported by the code, which is generic over T and contains no reference to a master list; the term appears to be carried over from a different/specialized method." -->
/// <param name="entity">The entity to persist; its <c>Id</c> property is used to locate the existing document to replace.</param>
/// <!-- aidoc:v1 sig=019b691 body=863650a -->
public async Task Update(T entity)
{
try
@@ -171,17 +168,11 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Finds a master list entity by its ID with options projection limited to 100 items.
/// 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.
/// </summary>
/// <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
/// "Summary says 'master list entity' but the method is generic on type T, not specifically MasterList." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Returns tag says 'The MasterList entity' but the method returns Task<T?> for a generic type T." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "Documents <exception cref='Exception'> but the catch block swallows exceptions and returns null; the method does not throw." -->
/// <param name="id">The <see cref="ObjectId"/> used to build the equality filter against the entity's identifier.</param>
/// <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>
/// <!-- aidoc:v1 sig=81ac96a body=1519944 -->
public async Task<T?> FindById(ObjectId id)
{
try
@@ -205,16 +196,13 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Finds a specific option within a master list by master and option IDs with locale translation.
/// Uses MongoDB aggregation to apply translations and return the translated option.
/// Retrieves a single <see cref="OptionList"/> item identified by <paramref name="masterId"/> and <paramref name="optionId"/>, applying locale-based translation. When <paramref name="locale"/> is <see cref="LocaleEnum.Default"/> or matches the document's default locale, the base option name is used; otherwise the method looks up a translation in the option's locale items and falls back to the base name when no translation exists. Returns <c>null</c> when no matching option is found or when an error is encountered.
/// </summary>
/// <param name="masterId">The ObjectId of the master list.</param>
/// <param name="optionId">The ObjectId of the option to retrieve.</param>
/// <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 body in a try-catch that catches all Exception instances and returns null; no exception is ever thrown to the caller, so the <exception cref=\"Exception\"> tag is misleading." -->
/// <param name="masterId">The identifier of the master document that owns the options collection.</param>
/// <param name="optionId">The identifier of the specific option to retrieve.</param>
/// <param name="locale">The desired locale used to select translated content.</param>
/// <returns>A <see cref="Task"/> that yields the matching <see cref="OptionList"/>, or <c>null</c> if the option does not exist or the lookup fails.</returns>
/// <!-- aidoc:v1 sig=fdb2628 body=0e4983e -->
public async Task<OptionList?> FindOptionItemById(ObjectId masterId, ObjectId optionId, LocaleEnum locale)
{
try
@@ -386,17 +374,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Finds a master list entity by its ID with optional locale translation for options.
/// Uses MongoDB aggregation to unwind options and apply translations.
/// Retrieves an entity of type <c>T</c> by its <see cref="ObjectId"/> identifier, applying locale-aware resolution of option names through a MongoDB aggregation pipeline. When <paramref name="locale"/> is <see langword="null"/>, equals <see cref="LocaleEnum.Default"/>, or matches the document's <c>defaultLocale</c>, the original option name is returned; otherwise, the translated name from <c>localeItems</c> is used with a fallback to the original name when no translation exists. Any exception is logged and swallowed, returning <see langword="null"/>.
/// </summary>
/// <param name="id">The ObjectId of the entity to retrieve.</param>
/// <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=medium kind=extra_exception
/// "The <exception cref=\"Exception\"/> tag indicates the method can throw Exception, but the body catches all Exception and returns null, so it never throws." -->
/// <!-- aidoc-review:v1 severity=medium kind=wrong_returns
/// "Returns Task<T?> generically, but the doc describes the return as 'The MasterList entity'. The actual generic type is not constrained to MasterList." -->
/// <param name="id">The <see cref="ObjectId"/> of the document to retrieve.</param>
/// <param name="locale">The optional <see cref="LocaleEnum"/> used to resolve translated option names. When omitted or set to <see cref="LocaleEnum.Default"/>, the original names are used.</param>
/// <returns>A <see cref="Task{T}"/> that yields the matching entity, or <see langword="null"/> when no document is found or an error is logged.</returns>
/// <!-- aidoc:v1 sig=cb4a658 body=f2e88d8 -->
public async Task<T?> FindById(ObjectId id, LocaleEnum? locale)
{
try
@@ -574,17 +557,13 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Finds a master list entity by its name.
/// Asynchronously searches the underlying collection for an entity matching the specified <paramref name="name"/>,
/// projecting the <c>options</c> field to a maximum of 100 elements to limit the payload size.
/// Returns <see langword="null"/> if no entity is found or if an error occurs while querying the collection.
/// </summary>
/// <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_summary
/// "Summary describes a 'master list entity' but the method is generic over type T and is not specific to master lists." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Documents the return as 'The MasterList entity' but the method returns Task<T?> where T is a generic type parameter." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_exception
/// "The method's try/catch catches every Exception and returns null, so no Exception is propagated to callers; the <exception> tag misrepresents the behavior." -->
/// <param name="name">The name of the entity to search for. Used to build an equality filter against the <c>Name</c> field.</param>
/// <returns>A <see cref="Task{T}"/> that yields the matching entity of type <c>T</c>, or <see langword="null"/> when no match is found or an error is logged.</returns>
/// <!-- aidoc:v1 sig=80a1541 body=8b5b558 -->
public async Task<T?> FindByName(string name)
{
try
@@ -620,14 +599,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Retrieves paginated master lists with optional text filtering.
/// 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.
/// 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>
/// <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
/// "The summary states the method 'retrieves paginated master lists', but the method does not perform any pagination (no Skip/Limit calls) and does not 'retrieve' results—it only builds a fluent query. The actual pagination would need to be applied by the caller on the returned IFindFluent." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "The returns description says 'A fluent queryable for MasterList results', but the method's return type is IFindFluent<T, T>—a generic fluent queryable, not specific to MasterList. The type parameter T is not constrained to MasterList." -->
/// <param name="filter">The <see cref="PaginationFilter"/> containing the optional <c>FilteredRequest.Text</c> used to match the <c>Name</c> field.</param>
/// <returns>An <see cref="IFindFluent{TDocument, TProjection}"/> representing the sorted, filtered query against the collection of <typeparamref name="T"/>.</returns>
/// <!-- aidoc:v1 sig=bbb39c7 body=f42ebaa -->
public IFindFluent<T, T> GetPaginatedMasterList(PaginationFilter filter)
{
var filterBuilder = Builders<T>.Filter;
@@ -650,13 +627,13 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Retrieves paginated options within a master list with optional text filtering.
/// Asynchronously retrieves options from the master list identified by <paramref name="listId"/>, optionally applying a case-insensitive text filter against each option's name, description, and option type.
/// Returns an empty list when no master list matches the supplied identifier.
/// </summary>
/// <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 states the method 'retrieves paginated options', but the code performs no pagination (no Skip/Take); only the filter's text is applied, and all matching options are returned via .ToList()." -->
/// <param name="filter">A <see cref="PaginationFilter"/> whose <c>FilteredRequest.Text</c>, when provided, is used to narrow the options by matching against the name, description, or option type.</param>
/// <param name="listId">The identifier of the master list whose options should be returned.</param>
/// <returns>A task that resolves to a <see cref="List{OptionList}"/> containing the matching options, or an empty list if the master list is not found.</returns>
/// <!-- aidoc:v1 sig=2ac8d75 body=b25fb18 -->
public async Task<List<OptionList>> GetPaginatedOptions(PaginationFilter filter, ObjectId listId)
{
//TODO: LOCALE
@@ -676,16 +653,14 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Adds a new option to a master list.
/// Adds a new <see cref="OptionList"/> to the master list identified by <paramref name="id"/>.
/// Returns null if a matching option already exists, if the update modifies no documents, or if an exception is thrown.
/// When the request comes from the admin panel, the locale items from <paramref name="opt"/> are reused; otherwise, a new locale entry is generated based on the current default locale of the list.
/// </summary>
/// <param name="id">The ObjectId of the master list.</param>
/// <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=wrong_returns
/// "The <returns> description states null is returned 'if duplicate exists', but null is also returned when UpdateOneAsync's ModifiedCount == 0 (e.g., document not found) and when an exception is caught, not solely on duplicate." -->
/// <!-- aidoc-review:v1 severity=medium kind=wrong_exception
/// "<exception cref=\"Exception\"> describes logging and returning null, but the code catches the exception from UpdateOneAsync rather than letting it propagate. Other parts of the method (e.g., GetMasterListByIdAndSearchOptions, FindById) are not wrapped in try/catch and could throw unhandled exceptions." -->
/// <param name="id">The <see cref="ObjectId"/> of the master list to update.</param>
/// <param name="opt">The <see cref="FilterOptionListElement"/> describing the option to add.</param>
/// <returns>A <see cref="Task{T}"/> containing the created <see cref="OptionList"/> on success, or null if the operation does not persist any change.</returns>
/// <!-- aidoc:v1 sig=1602f0d body=e7fd138 -->
public async Task<OptionList?> AddOptionToMasterList(ObjectId id, FilterOptionListElement opt)
{
var exist = await GetMasterListByIdAndSearchOptions(id, opt);
@@ -725,12 +700,11 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Retrieves all master list entities.
/// Retrieves all entities of type <typeparamref name="T"/> from the data store asynchronously.
/// If an error occurs during retrieval, it is logged and an empty collection is returned instead of propagating the exception.
/// </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=extra_exception
/// "The method catches all exceptions internally and returns an empty list; it does not throw Exception to callers, so the <exception cref=\"Exception\"/> tag is misleading." -->
/// <returns>A task that yields an <see cref="IEnumerable{T}"/> containing all entities, or an empty collection when an error is encountered.</returns>
/// <!-- aidoc:v1 sig=3a61c61 body=40d7129 -->
public async Task<IEnumerable<T>> GetAll()
{
try
@@ -746,14 +720,10 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Retrieves all master list entities without options, returning only metadata.
/// Retrieves every entry from the master list collection and projects each into a <see cref="MasterListDto"/>, where <see cref="MasterListDto.Options"/> contains the total count of options. If the underlying query fails, the exception is logged and an empty collection is returned.
/// </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 <exception cref=\"Exception\"> tag implies the method throws Exception, but the body catches all exceptions and returns an empty list — it never propagates." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Summary says 'Retrieves all master list entities without options', which reads as filtering for entities that have no options, but the code uses FilterDefinition<T>.Empty (no filter) and returns all entities with Options reduced to a count." -->
/// <returns>A task that resolves to an <see cref="IEnumerable{MasterListDto}"/> containing all master list entries, or an empty collection when an error occurs.</returns>
/// <!-- aidoc:v1 sig=e493435 body=1c299ba -->
public async Task<IEnumerable<MasterListDto>> GetAllWithoutOptions()
{
try
@@ -778,12 +748,11 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Counts the total number of master list entities in the collection.
/// Asynchronously counts the total number of documents in the underlying collection.
/// If the operation fails, the exception is logged and the method returns 0 as a fallback value.
/// </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=extra_exception
/// "The method catches all exceptions internally and returns 0, so it does not propagate Exception to callers. The <exception cref=\"Exception\"/> tag is misleading." -->
/// <returns>A <see cref="Task{Int32}"/> representing the asynchronous operation, containing the total document count, or 0 if an error occurred.</returns>
/// <!-- aidoc:v1 sig=f1f0a98 body=01cd3d1 -->
public async Task<int> Count()
{
try
@@ -1178,14 +1147,15 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Updates the metadata details for a master list.
/// Updates the option details of an existing master list document identified by <paramref name="id"/>, applying only the
/// fields that are provided in <paramref name="opt"/> (<c>CanAddElement</c> and <c>OptionListDetails</c>) using a partial
/// <c>$set</c> update. Returns the supplied <see cref="UpdateMasterListDetailsDto"/> when the document is found and modified,
/// or <see langword="null"/> when no document matches the filter, no fields are modified, or the operation fails.
/// </summary>
/// <param name="id">The ObjectId of the master list.</param>
/// <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 and handles Exception internally (returning null) rather than throwing it; the <exception cref=\"Exception\"> tag is therefore incorrect since no exception is propagated to the caller." -->
/// <param name="id">The <see cref="MongoDB.Bson.ObjectId"/> identifier of the master list document to update.</param>
/// <param name="opt">The <see cref="UpdateMasterListDetailsDto"/> containing the new values; only non-null properties are applied to the document.</param>
/// <returns>A <see cref="Task{UpdateMasterListDetailsDto}"/> that resolves to the updated DTO on success, or <see langword="null"/> if the document was not found, was not modified, or an error was logged.</returns>
/// <!-- aidoc:v1 sig=53d4179 body=49f50ca -->
public async Task<UpdateMasterListDetailsDto?> UpdateOptionDetailsToMasterList(ObjectId id,
UpdateMasterListDetailsDto opt)
{
@@ -1215,14 +1185,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Updates the name of a master list.
/// Updates the <see cref="Name"/> of the master list entry identified by <paramref name="id"/>.
/// </summary>
/// <param name="id">The ObjectId of the master list.</param>
/// <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 in a try/catch and returns false; it never throws Exception to the caller, so the <exception cref=\"Exception\"> tag is incorrect." -->
/// <param name="id">The identifier of the master list entry to update.</param>
/// <param name="name">The new name to assign to the master list entry.</param>
/// <returns><see langword="true"/> if the document was modified; otherwise, <see langword="false"/>, including when the update fails due to an exception.</returns>
/// <!-- aidoc:v1 sig=5b79a51 body=36dfe99 -->
public async Task<bool> UpdateMasterListName(ObjectId id, string name)
{
var filter = Builders<T>.Filter.And(
@@ -1243,14 +1211,13 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Updates the description of a master list.
/// Updates the <c>Description</c> field of the document identified by <paramref name="id"/> in the master list collection.
/// Returns <see langword="true"/> when the update modified at least one document, and <see langword="false"/> when no document was modified or when an error is caught and logged.
/// </summary>
/// <param name="id">The ObjectId of the master list.</param>
/// <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=medium kind=extra_exception
/// "The <exception cref=\"Exception\"/> tag implies the method throws, but the catch block handles all exceptions internally and the method never rethrows; the tag is misleading and should be removed." -->
/// <param name="id">The <see cref="ObjectId"/> of the document whose description should be updated.</param>
/// <param name="description">The new description value to set on the document.</param>
/// <returns>A <see cref="Task{Boolean}"/> that resolves to <see langword="true"/> if the document was modified, otherwise <see langword="false"/>.</returns>
/// <!-- aidoc:v1 sig=5a27a55 body=3552f46 -->
public async Task<bool> UpdateMasterListDescription(ObjectId id, string description)
{
var filter = Builders<T>.Filter.And(
@@ -1271,14 +1238,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Removes an option from a master list by matching all its properties.
/// Removes the specified <paramref name="oldOpt"/> entry from the "options" array of the MasterList document identified by <paramref name="id"/>, matching on all of the option's properties (name, option type, icons, colors, default flag, and description). Returns <see langword="true"/> when the document was modified (the option was found and pulled), and <see langword="false"/> when no document was modified or when the update fails and the exception is logged.
/// </summary>
/// <param name="id">The ObjectId of the master list.</param>
/// <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=wrong_exception
/// "The method catches all Exception types and returns false; it does not throw Exception, so listing it as a thrown exception is misleading." -->
/// <param name="id">The <see cref="ObjectId"/> of the MasterList document to update.</param>
/// <param name="oldOpt">The <see cref="OptionList"/> instance whose properties define the filter used to pull the matching entry from the "options" array.</param>
/// <returns>A <see cref="Task{Boolean}"/> that resolves to <see langword="true"/> if an option was successfully removed, otherwise <see langword="false"/>.</returns>
/// <!-- aidoc:v1 sig=8de50cd body=d974b9b -->
public async Task<bool> RemoveMasterListOption(ObjectId id, OptionList oldOpt)
{
var filter = Builders<T>.Filter.Eq("_id", id);
@@ -1307,11 +1272,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Creates necessary indexes for the MasterList collection.
/// Currently creates text indexes for DiagnosisList on options.name, options.description, and options._id.
/// Creates MongoDB indexes on the underlying collection when the document type is <see cref="DiagnosisList"/>.
/// Three ascending indexes are created on the <c>options.name</c>, <c>options.description</c>, and <c>options._id</c> fields,
/// configured with <c>Background = true</c>, <c>Unique = false</c>, and Spanish text indexing via <c>LanguageOverride</c> and <c>DefaultLanguage</c>.
/// For any other type <typeparamref name="T"/>, no indexes are created.
/// </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 regular ascending B-tree indexes, not text indexes." -->
/// <!-- aidoc:v1 sig=4955da2 body=2c8d1f7 -->
public override async Task CreateIndexes()
{
if (typeof(T) == typeof(DiagnosisList))
@@ -1423,13 +1389,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Creates a fluent query for paginated results with combined filters.
/// Builds a fluent MongoDB find query against the collection, combining the supplied <paramref name="filters"/> with a logical AND when any are present, or using an empty filter that matches every document when the list is empty. The returned query is pre-configured with the given <paramref name="sort"/> ordering.
/// </summary>
/// <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 summary states the method creates a query 'for paginated results', but the code contains no pagination logic (no Skip/Limit calls); it only applies a combined filter and sort before returning the IFindFluent." -->
/// <param name="filters">List of <see cref="FilterDefinition{T}"/> predicates to apply; an empty list results in no filtering.</param>
/// <param name="sort">The <see cref="SortDefinition{T}"/> ordering applied to the results.</param>
/// <returns>An <see cref="IFindFluent{T, T}"/> representing the configured find operation.</returns>
/// <!-- aidoc:v1 sig=704d715 body=2a35652 -->
private IFindFluent<T, T> CreateFindFluent(List<FilterDefinition<T>> filters, SortDefinition<T> sort)
{
var combinedFilter = filters.Any()
@@ -1439,14 +1404,12 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Generates new locale items for a master list option based on a default locale.
/// Creates LocaleItem entries for all locales except the specified default.
/// Creates a new <see cref="Locale"/> instance and populates each property whose name matches a <see cref="LocaleEnum"/> value, excluding <see cref="LocaleEnum.Default"/> and the value supplied in <paramref name="localeList"/>, with a new <see cref="LocaleItem"/> whose <see cref="LocaleItem.Name"/> is set to <paramref name="opt"/>.
/// </summary>
/// <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
/// "Summary states 'Creates LocaleItem entries for all locales except the specified default' but the code also explicitly excludes the LocaleEnum.Default value in addition to the localeList parameter, so two locales are skipped, not one." -->
/// <param name="localeList">The <see cref="LocaleEnum"/> value to skip when populating the new <see cref="Locale"/>.</param>
/// <param name="opt">The name assigned to each created <see cref="LocaleItem"/> entry.</param>
/// <returns>A <see cref="Locale"/> with its matching <see cref="LocaleItem"/> properties initialized, except for the omitted locale.</returns>
/// <!-- aidoc:v1 sig=147db59 body=9b63847 -->
private Locale GetNewItemLocale(LocaleEnum localeList, string opt)
{
var newLocale = new Locale();
@@ -1520,16 +1483,18 @@ public class MasterListRepository<T> : MongoRepository<T>, IMasterListRepository
}
/// <summary>
/// Searches for options within a master list by name with locale translation.
/// Uses MongoDB aggregation pipeline to apply locale-aware filtering.
/// Retrieves the options of a master list document identified by <paramref name="id"/>, applying locale-aware
/// translation of the option name and filtering the results to those whose translated name matches
/// <paramref name="newOptName"/>. When the requested <paramref name="locale"/> matches the document's default
/// 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>
/// <param name="id">The ObjectId of the master list.</param>
/// <param name="newOptName">The option name to search for.</param>
/// <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 method catches all exceptions internally (catch (Exception ex)) and returns an empty list; no exceptions are propagated, so documenting <exception cref=\"Exception\"> is misleading." -->
/// <param name="id">The <see cref="MongoDB.Bson.ObjectId"/> of the master list document to query.</param>
/// <param name="newOptName">The option name to match against the locale-resolved name of each option.</param>
/// <param name="locale">The <see cref="LocaleEnum"/> value used to select the translated name for each option.</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>
/// <!-- aidoc:v1 sig=342dc63 body=21f31fc -->
private async Task<List<OptionList>> GetMasterListByIdAndTextSearch(
ObjectId id, string newOptName, LocaleEnum locale)
{
+26 -32
View File
@@ -157,25 +157,23 @@ public class LdapLoginService : ILoginService
}
/// <summary>
/// This method is not implemented in the LdapLoginService, as the login process is handled through the Login(string username, string password) method.
/// Authenticates a user using the provided HTTP context. The implementation is not yet provided and the method always throws a <see cref="LoginServicesException"/>.
/// </summary>
/// <param name="context">The HTTP context of the request.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="LoginServicesException">Thrown when the method is not implemented.</exception>
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "The method returns Task<User> but the documentation only says 'A task representing the asynchronous operation' without mentioning the User return type, misleading readers about the actual return contract." -->
/// <param name="context">The current <see cref="HttpContext"/> carrying the request data used for authentication.</param>
/// <returns>A <see cref="Task{User}"/> that will resolve to the authenticated user once the method is implemented.</returns>
/// <exception cref="LoginServicesException">Thrown because the login operation has not been implemented.</exception>
/// <!-- aidoc:v1 sig=851dc90 -->
public Task<User> Login(HttpContext context)
=> throw new LoginServicesException("Not implemented");
/// <summary>
/// This method is not implemented in the LdapLoginService, as the authentication process is handled through the Login(string username, string password) method.
/// Authenticates a user with the provided <paramref name="username"/> and <paramref name="password"/>.
/// </summary>
/// <param name="username">The username of the user to authenticate.</param>
/// <param name="password">The password of the user to authenticate.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="LoginServicesException">Thrown when the method is not implemented.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=wrong_returns
/// "The <returns> tag says 'A task representing the asynchronous operation' but the method returns Task<User>; the documented return type omits the User result." -->
/// <param name="username">The username of the user attempting to authenticate.</param>
/// <param name="password">The password of the user attempting to authenticate.</param>
/// <returns>A <see cref="Task{User}"/> that represents the asynchronous authentication operation, yielding the authenticated <see cref="User"/> on success.</returns>
/// <exception cref="LoginServicesException">Thrown because the authentication operation is not yet implemented.</exception>
/// <!-- aidoc:v1 sig=a0b1f46 -->
public Task<User> Authenticate(string username, string password)
=> throw new LoginServicesException("Not implemented");
@@ -190,24 +188,23 @@ public class LdapLoginService : ILoginService
=> throw new LoginServicesException("Not implemented");
/// <summary>
/// This method is not implemented in the LdapLoginService, as the user retrieval process is handled through the Login(string username, string password) method and the GetOrCreateUser(User userEntryLdap, LdapEntry entry) method.
/// Retrieves a <see cref="User"/> matching the supplied email address, or <see langword="null"/> when no user is found.
/// </summary>
/// <param name="email">The email of the user to retrieve.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="LoginServicesException">Thrown when the method is not implemented.</exception>
/// <!-- aidoc-review:v1 severity=medium kind=missing_returns
/// "The method returns Task<User?>, but the <returns> description only says 'A task representing the asynchronous operation' without mentioning the User? result type." -->
/// <param name="email">The email address used to look up the <see cref="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>
/// <exception cref="LoginServicesException">Thrown because the operation is not implemented.</exception>
/// <!-- aidoc:v1 sig=ba92b09 -->
public Task<User?> GetByEmail(string email)
=> throw new LoginServicesException("Not implemented");
/// <summary>
/// This method is not implemented in the LdapLoginService, as the user retrieval process is handled through the Login(string username, string password) method and the GetOrCreateUser(User userEntryLdap, LdapEntry entry) method.
/// Asynchronously retrieves a <see cref="User"/> by the supplied <paramref name="username"/>.
/// The current implementation always throws <see cref="LoginServicesException"/> because the operation is not implemented.
/// </summary>
/// <param name="username">The username of the user to retrieve.</param>
/// <returns>A task representing the asynchronous operation.</returns>
/// <exception cref="LoginServicesException">Thrown when the method is not implemented.</exception>
/// <!-- aidoc-review:v1 severity=low kind=missing_returns
/// "The <returns> description 'A task representing the asynchronous operation' omits the User? type that the Task would contain, as declared in the method signature Task<User?>." -->
/// <param name="username">The username used to look up the <see cref="User"/>.</param>
/// <returns>A <see cref="Task{TResult}"/> that resolves to the matching <see cref="User"/>, or <see langword="null"/> if no user is found.</returns>
/// <exception cref="LoginServicesException">Thrown for every invocation because the operation is not implemented.</exception>
/// <!-- aidoc:v1 sig=5184c30 -->
public Task<User?> GetByUsername(string username)
=> throw new LoginServicesException("Not implemented");
@@ -343,14 +340,11 @@ public class LdapLoginService : ILoginService
/// <summary>
/// This method retrieves a list of authorities for a user based on the LDAP entry and the application's configuration for mapping LDAP groups to authorities.
/// Constructs a <see cref="User"/> from the attributes of the supplied <paramref name="ldapEntry"/>, mapping the LDAP username, first name, and last name properties according to the current configuration. The username falls back to an empty string when the configured attribute is missing, and first/last name values are only applied when their corresponding configuration entries are set and the LDAP entry exposes those attributes, with the last name appended to the first name when both are available.
/// </summary>
/// <param name="ldapEntry">The LDAP entry containing the user's information.</param>
/// <returns>The existing or newly created user with updated authorities.</returns>
/// <!-- aidoc-review:v1 severity=high kind=wrong_summary
/// "Summary describes retrieving a list of authorities and mapping LDAP groups to authorities, but the method actually constructs a User object with UserName, first name, and last name from LDAP attributes." -->
/// <!-- aidoc-review:v1 severity=high kind=wrong_returns
/// "Returns description states 'The existing or newly created user with updated authorities', but the method always creates a new User with name information and never deals with authorities or existing users." -->
/// <param name="ldapEntry">The <see cref="LdapEntry"/> whose attributes are read to populate the <see cref="User"/>.</param>
/// <returns>A <see cref="User"/> populated from the <paramref name="ldapEntry"/> attributes.</returns>
/// <!-- aidoc:v1 sig=947181a body=33ffec8 -->
private User GetUser(LdapEntry ldapEntry)
{