diff --git a/adas-core.Infrastructure/Repositories/MasterListRepository.cs b/adas-core.Infrastructure/Repositories/MasterListRepository.cs index a42ee64a..5cddb35d 100644 --- a/adas-core.Infrastructure/Repositories/MasterListRepository.cs +++ b/adas-core.Infrastructure/Repositories/MasterListRepository.cs @@ -114,14 +114,11 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Updates an existing master list entity with full replacement. + /// Replaces the document matching '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. /// - /// The entity with updated values. - /// Throws and re-throws exceptions after logging. - /// - /// + /// The entity to persist; its Id property is used to locate the existing document to replace. + /// public async Task Update(T entity) { try @@ -171,17 +168,11 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Finds a master list entity by its ID with options projection limited to 100 items. + /// Asynchronously finds an entity by its , 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 null is returned. /// - /// The ObjectId of the entity to retrieve. - /// The MasterList entity if found; otherwise, null. - /// Logs errors and returns null on failure. - /// - /// - /// + /// The used to build the equality filter against the entity's identifier. + /// A that yields the matching entity, or null when no document is found or the operation fails. + /// public async Task FindById(ObjectId id) { try @@ -205,16 +196,13 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// 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 item identified by and , applying locale-based translation. When is 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 null when no matching option is found or when an error is encountered. /// - /// The ObjectId of the master list. - /// The ObjectId of the option to retrieve. - /// The locale for translation. - /// The OptionList with translated fields if found; otherwise, null. - /// Logs errors and returns null on failure. - /// + /// The identifier of the master document that owns the options collection. + /// The identifier of the specific option to retrieve. + /// The desired locale used to select translated content. + /// A that yields the matching , or null if the option does not exist or the lookup fails. + /// public async Task FindOptionItemById(ObjectId masterId, ObjectId optionId, LocaleEnum locale) { try @@ -386,17 +374,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// 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 T by its identifier, applying locale-aware resolution of option names through a MongoDB aggregation pipeline. When is , equals , or matches the document's defaultLocale, the original option name is returned; otherwise, the translated name from localeItems is used with a fallback to the original name when no translation exists. Any exception is logged and swallowed, returning . /// - /// The ObjectId of the entity to retrieve. - /// Optional locale for translated option names. - /// The MasterList entity with translated options if found; otherwise, null. - /// Logs errors and returns null on failure. - /// - /// + /// The of the document to retrieve. + /// The optional used to resolve translated option names. When omitted or set to , the original names are used. + /// A that yields the matching entity, or when no document is found or an error is logged. + /// public async Task FindById(ObjectId id, LocaleEnum? locale) { try @@ -574,17 +557,13 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Finds a master list entity by its name. + /// Asynchronously searches the underlying collection for an entity matching the specified , + /// projecting the options field to a maximum of 100 elements to limit the payload size. + /// Returns if no entity is found or if an error occurs while querying the collection. /// - /// The name of the master list to retrieve. - /// The MasterList entity if found; otherwise, null. - /// Logs errors and returns null on failure. - /// - /// - /// + /// The name of the entity to search for. Used to build an equality filter against the Name field. + /// A that yields the matching entity of type T, or when no match is found or an error is logged. + /// public async Task FindByName(string name) { try @@ -620,14 +599,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Retrieves paginated master lists with optional text filtering. + /// Builds a sorted master-list query for documents of type , returning all documents ordered ascending by the name field, or only those whose Name matches 's search text via a case-insensitive regex (with special characters escaped) when provided. + /// If is null, its FilteredRequest is null, or FilteredRequest.Text is null or empty, no additional filter is applied and the unfiltered, sorted result is returned. /// - /// The pagination and filtering parameters. - /// A fluent queryable for MasterList results. - /// - /// + /// The containing the optional FilteredRequest.Text used to match the Name field. + /// An representing the sorted, filtered query against the collection of . + /// public IFindFluent GetPaginatedMasterList(PaginationFilter filter) { var filterBuilder = Builders.Filter; @@ -650,13 +627,13 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Retrieves paginated options within a master list with optional text filtering. + /// Asynchronously retrieves options from the master list identified by , 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. /// - /// The pagination and filtering parameters. - /// The ObjectId of the master list. - /// A list of filtered OptionList items. - /// + /// A whose FilteredRequest.Text, when provided, is used to narrow the options by matching against the name, description, or option type. + /// The identifier of the master list whose options should be returned. + /// A task that resolves to a containing the matching options, or an empty list if the master list is not found. + /// public async Task> GetPaginatedOptions(PaginationFilter filter, ObjectId listId) { //TODO: LOCALE @@ -676,16 +653,14 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Adds a new option to a master list. + /// Adds a new to the master list identified by . + /// 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 are reused; otherwise, a new locale entry is generated based on the current default locale of the list. /// - /// The ObjectId of the master list. - /// The option element to add. - /// The newly created OptionList if successful; otherwise, null if duplicate exists. - /// Logs errors and returns null on failure. - /// - /// + /// The of the master list to update. + /// The describing the option to add. + /// A containing the created on success, or null if the operation does not persist any change. + /// public async Task AddOptionToMasterList(ObjectId id, FilterOptionListElement opt) { var exist = await GetMasterListByIdAndSearchOptions(id, opt); @@ -725,12 +700,11 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Retrieves all master list entities. + /// Retrieves all entities of type 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. /// - /// An enumerable of all MasterList entities. - /// Logs errors and returns empty list on failure. - /// + /// A task that yields an containing all entities, or an empty collection when an error is encountered. + /// public async Task> GetAll() { try @@ -746,14 +720,10 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Retrieves all master list entities without options, returning only metadata. + /// Retrieves every entry from the master list collection and projects each into a , where contains the total count of options. If the underlying query fails, the exception is logged and an empty collection is returned. /// - /// An enumerable of MasterListDto containing id, name, description, listType, and options count. - /// Logs errors and returns empty list on failure. - /// - /// + /// A task that resolves to an containing all master list entries, or an empty collection when an error occurs. + /// public async Task> GetAllWithoutOptions() { try @@ -778,12 +748,11 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// 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. /// - /// The total count of entities. - /// Logs errors and returns 0 on failure. - /// + /// A representing the asynchronous operation, containing the total document count, or 0 if an error occurred. + /// public async Task Count() { try @@ -1178,14 +1147,15 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Updates the metadata details for a master list. + /// Updates the option details of an existing master list document identified by , applying only the + /// fields that are provided in (CanAddElement and OptionListDetails) using a partial + /// $set update. Returns the supplied when the document is found and modified, + /// or when no document matches the filter, no fields are modified, or the operation fails. /// - /// The ObjectId of the master list. - /// The UpdateMasterListDetailsDto with updated values. - /// The updated UpdateMasterListDetailsDto if successful; otherwise, null. - /// Logs errors and returns null on failure. - /// + /// The identifier of the master list document to update. + /// The containing the new values; only non-null properties are applied to the document. + /// A that resolves to the updated DTO on success, or if the document was not found, was not modified, or an error was logged. + /// public async Task UpdateOptionDetailsToMasterList(ObjectId id, UpdateMasterListDetailsDto opt) { @@ -1215,14 +1185,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Updates the name of a master list. + /// Updates the of the master list entry identified by . /// - /// The ObjectId of the master list. - /// The new name. - /// True if the update was successful; otherwise, false. - /// Logs errors and returns false on failure. - /// + /// The identifier of the master list entry to update. + /// The new name to assign to the master list entry. + /// if the document was modified; otherwise, , including when the update fails due to an exception. + /// public async Task UpdateMasterListName(ObjectId id, string name) { var filter = Builders.Filter.And( @@ -1243,14 +1211,13 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Updates the description of a master list. + /// Updates the Description field of the document identified by in the master list collection. + /// Returns when the update modified at least one document, and when no document was modified or when an error is caught and logged. /// - /// The ObjectId of the master list. - /// The new description. - /// True if the update was successful; otherwise, false. - /// Logs errors and returns false on failure. - /// + /// The of the document whose description should be updated. + /// The new description value to set on the document. + /// A that resolves to if the document was modified, otherwise . + /// public async Task UpdateMasterListDescription(ObjectId id, string description) { var filter = Builders.Filter.And( @@ -1271,14 +1238,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Removes an option from a master list by matching all its properties. + /// Removes the specified entry from the "options" array of the MasterList document identified by , matching on all of the option's properties (name, option type, icons, colors, default flag, and description). Returns when the document was modified (the option was found and pulled), and when no document was modified or when the update fails and the exception is logged. /// - /// The ObjectId of the master list. - /// The OptionList to remove. - /// True if the option was removed; otherwise, false. - /// Logs errors and returns false on failure. - /// + /// The of the MasterList document to update. + /// The instance whose properties define the filter used to pull the matching entry from the "options" array. + /// A that resolves to if an option was successfully removed, otherwise . + /// public async Task RemoveMasterListOption(ObjectId id, OptionList oldOpt) { var filter = Builders.Filter.Eq("_id", id); @@ -1307,11 +1272,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// 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 . + /// Three ascending indexes are created on the options.name, options.description, and options._id fields, + /// configured with Background = true, Unique = false, and Spanish text indexing via LanguageOverride and DefaultLanguage. + /// For any other type , no indexes are created. /// - /// + /// public override async Task CreateIndexes() { if (typeof(T) == typeof(DiagnosisList)) @@ -1423,13 +1389,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// Creates a fluent query for paginated results with combined filters. + /// Builds a fluent MongoDB find query against the collection, combining the supplied 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 ordering. /// - /// List of filter definitions to apply. - /// Sort definition for the query results. - /// A fluent queryable for T results. - /// + /// List of predicates to apply; an empty list results in no filtering. + /// The ordering applied to the results. + /// An representing the configured find operation. + /// private IFindFluent CreateFindFluent(List> filters, SortDefinition sort) { var combinedFilter = filters.Any() @@ -1439,14 +1404,12 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// 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 instance and populates each property whose name matches a value, excluding and the value supplied in , with a new whose is set to . /// - /// The default locale to exclude from translations. - /// The option name to use as default translation. - /// A Locale object with translations for all other locales. - /// + /// The value to skip when populating the new . + /// The name assigned to each created entry. + /// A with its matching properties initialized, except for the omitted locale. + /// private Locale GetNewItemLocale(LocaleEnum localeList, string opt) { var newLocale = new Locale(); @@ -1520,16 +1483,18 @@ public class MasterListRepository : MongoRepository, IMasterListRepository } /// - /// 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 , applying locale-aware + /// translation of the option name and filtering the results to those whose translated name matches + /// . When the requested 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. /// - /// The ObjectId of the master list. - /// The option name to search for. - /// The locale for translation. - /// A list of matching OptionList items ordered by name. - /// Logs errors and returns empty list on failure. - /// + /// The of the master list document to query. + /// The option name to match against the locale-resolved name of each option. + /// The value used to select the translated name for each option. + /// A containing a of matching options ordered by name, or an empty list when no options match or an error occurs. + /// private async Task> GetMasterListByIdAndTextSearch( ObjectId id, string newOptName, LocaleEnum locale) { diff --git a/adas-core.LdapLogin/LdapLoginService.cs b/adas-core.LdapLogin/LdapLoginService.cs index eb3d18b7..19a940d0 100644 --- a/adas-core.LdapLogin/LdapLoginService.cs +++ b/adas-core.LdapLogin/LdapLoginService.cs @@ -157,25 +157,23 @@ public class LdapLoginService : ILoginService } /// - /// 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 . /// - /// The HTTP context of the request. - /// A task representing the asynchronous operation. - /// Thrown when the method is not implemented. - /// + /// The current carrying the request data used for authentication. + /// A that will resolve to the authenticated user once the method is implemented. + /// Thrown because the login operation has not been implemented. + /// public Task Login(HttpContext context) => throw new LoginServicesException("Not implemented"); /// - /// 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 and . /// - /// The username of the user to authenticate. - /// The password of the user to authenticate. - /// A task representing the asynchronous operation. - /// Thrown when the method is not implemented. - /// + /// The username of the user attempting to authenticate. + /// The password of the user attempting to authenticate. + /// A that represents the asynchronous authentication operation, yielding the authenticated on success. + /// Thrown because the authentication operation is not yet implemented. + /// public Task Authenticate(string username, string password) => throw new LoginServicesException("Not implemented"); @@ -190,24 +188,23 @@ public class LdapLoginService : ILoginService => throw new LoginServicesException("Not implemented"); /// - /// 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 matching the supplied email address, or when no user is found. /// - /// The email of the user to retrieve. - /// A task representing the asynchronous operation. - /// Thrown when the method is not implemented. - /// + /// The email address used to look up the . + /// A that resolves to the matching , or if no user exists for the given . + /// Thrown because the operation is not implemented. + /// public Task GetByEmail(string email) => throw new LoginServicesException("Not implemented"); /// - /// 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 by the supplied . + /// The current implementation always throws because the operation is not implemented. /// - /// The username of the user to retrieve. - /// A task representing the asynchronous operation. - /// Thrown when the method is not implemented. - /// + /// The username used to look up the . + /// A that resolves to the matching , or if no user is found. + /// Thrown for every invocation because the operation is not implemented. + /// public Task GetByUsername(string username) => throw new LoginServicesException("Not implemented"); @@ -343,14 +340,11 @@ public class LdapLoginService : ILoginService /// - /// 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 from the attributes of the supplied , 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. /// - /// The LDAP entry containing the user's information. - /// The existing or newly created user with updated authorities. - /// - /// + /// The whose attributes are read to populate the . + /// A populated from the attributes. + /// private User GetUser(LdapEntry ldapEntry) {