using adas_core.Application.Repositories.Interfaces; using adas_core.Domain.Models; using adas_core.Domain.Models.AppSettings; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using MongoUtils = adas_core.Infrastructure.Utils.MongoUtils; namespace adas_core.Infrastructure.Repositories; /// /// Repository for managing patient diagnoses in a MongoDB collection. Provides methods for CRUD operations and querying diagnoses by patient ID and code. /// public class DiagnosisRepository : MongoRepository, IDiagnosisRepository { private readonly ApiSettings _apiSettings; /// /// Initializes a new instance of the class with the specified API settings and MongoDB database. The API settings are used to determine the collection name for storing patient diagnoses. /// /// The API settings containing configuration for the repository. /// The MongoDB database instance. /// Thrown when the API settings are null. public DiagnosisRepository(IOptions apiSettings, IMongoDatabase database) : base(database) { if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings)); _apiSettings = apiSettings.Value; } //For testing /// /// Gets the name of the MongoDB collection for storing patient diagnoses. The collection name is determined by the API settings, and defaults to "patients_diagnosis" if not specified. /// /// The name of the MongoDB collection for patient diagnoses. public override string GetCollectionName() { return _apiSettings.PatientsDiagnosis ?? "patients_diagnosis"; } /// /// Retrieves a list of patient diagnoses for a given patient ID. The diagnoses are sorted in descending order by time, with the most recent diagnoses appearing first. /// /// The ID of the patient whose diagnoses are to be retrieved. /// A list of patient diagnoses for the specified patient ID. public async Task> GetByPatient(ObjectId patientId) { var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId); var result = await Collection.FindAsync(filter, new FindOptions { Sort = Builders.Sort.Descending("time") }); return result.ToList(); } /// /// Deletes a patient diagnosis by its ID. This method removes the diagnosis document from the MongoDB collection based on the provided ID. /// /// The ID of the patient diagnosis to delete. /// A task representing the asynchronous operation. public new async Task DeleteAsync(ObjectId id) { var filter = Builders.Filter.Eq(t => t.Id, id); await Collection.DeleteOneAsync(filter); } /// /// Inserts a new patient diagnosis into the MongoDB collection. This method adds a new diagnosis document to the collection based on the provided object. /// /// The patient diagnosis to insert. /// A task representing the asynchronous operation. public override async Task InsertOneAsync(PatientDiagnosis diagnosis) { await Collection.InsertOneAsync(diagnosis); } /// /// Deletes all patient diagnoses associated with a specific patient ID. This method removes all diagnosis documents from the MongoDB collection that match the provided patient ID. /// /// The ID of the patient whose diagnoses are to be deleted. /// public async Task DeleteByPatientId(ObjectId patientId) { var filter = Builders.Filter.Eq(po => po.PatientId, patientId); await Collection.DeleteManyAsync(filter); } /// /// Finds a patient diagnosis by patient ID, code, and coding system. /// This method retrieves a single diagnosis document from the MongoDB collection that matches the provided patient ID, code, and coding system. /// If no matching diagnosis is found, it returns null. /// /// The ID of the patient. /// The code of the diagnosis. /// The coding system of the diagnosis. /// The matching patient diagnosis, or null if not found. public async Task FindByPatientIdAndCode(ObjectId patientId, string? code, string? codingSystem) { var builder = Builders.Filter; var filter = builder.And( builder.Eq(ob => ob.PatientId, patientId), builder.Eq(ob => ob.Code, code), builder.Eq(ob => ob.CodingSystem, codingSystem) ); var result = await Collection.FindAsync(filter); return await result.FirstOrDefaultAsync(); } /// /// Finds patient diagnoses by patient ID. This method retrieves all diagnosis documents from the MongoDB collection that match the provided patient ID. /// The results are returned as an asynchronous cursor, allowing for efficient retrieval of large datasets. /// /// The ID of the patient whose diagnoses are to be retrieved. /// An asynchronous cursor of patient diagnoses. public async Task> FindByPatientIdAsync(ObjectId patientId) { var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId); return await Collection.FindAsync(filter); } /// /// Updates the patient ID for all diagnoses that match the old patient ID. /// This method performs a bulk update operation on the MongoDB collection, changing the patient ID from the old value to the new value for all matching diagnosis documents. /// /// The name ID associated with the patient. /// The new patient ID to be set. /// The old patient ID to be replaced. /// A task representing the asynchronous operation. public async Task UpdateManyObjectId(string nameId, ObjectId id, ObjectId oldId) { await UpdateManyObjectIdAsync(nameId, id, oldId); } /// /// Creates indexes for the patient diagnosis collection. This method ensures that the necessary indexes are created on the MongoDB collection to optimize query performance. /// /// A task representing the asynchronous operation. public override async Task CreateIndexes() { var options = new CreateIndexOptions { Background = true, Unique = false }; var indexes = new List> { new("{ patientid: 1 }", options) }; await MongoUtils.EnsureIndexes(Collection, indexes); } }