Files
adas-core/adas-core.Infrastructure/Repositories/PumpStateRepository.cs
T

115 lines
6.1 KiB
C#

using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Pumps;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
namespace adas_core.Infrastructure.Repositories
{
/// <summary>
/// Provides a repository implementation for <see cref="PumpState"/> entities backed by a MongoDB data store.
/// </summary>
/// <remarks>Inherits base functionality from <see cref="MongoRepository{T}"/> and implements the <see cref="IPumpStateRepository"/> contract.</remarks>
/// <!-- aidoc:v1 sig=e8fa3b3 -->
public class PumpStateRepository : MongoRepository<PumpState>, IPumpStateRepository
{
private readonly ApiSettings _apiSettings;
/// <summary>
/// Initializes a new instance of <see cref="PumpStateRepository"/>, storing the resolved <see cref="ApiSettings"/> from <paramref name="apiSettings"/> and passing the <see cref="IMongoDatabase"/> to the base class constructor.
/// </summary>
/// <param name="apiSettings">The <see cref="IOptions{ApiSettings}"/> providing the <see cref="ApiSettings"/> configuration values used by the repository.</param>
/// <param name="database">The <see cref="IMongoDatabase"/> forwarded to the base class to establish the underlying data connection.</param>
/// <!-- aidoc:v1 sig=48961b9 body=12fddac -->
public PumpStateRepository(IOptions<ApiSettings> apiSettings, IMongoDatabase database)
: base(database)
{
_apiSettings = apiSettings.Value;
}
/// <summary>
/// Retrieves the collection name for pump states, returning the configured value from API settings or the default name "pump_states" when the setting is not provided.
/// </summary>
/// <returns>The configured pump states collection name, or the default value "pump_states" if the setting is null.</returns>
/// <!-- aidoc:v1 sig=94e22ff body=31eaf80 -->
public override string GetCollectionName()
{
return _apiSettings.PumpStates ?? "pump_states";
}
/// <summary>
/// Creates the MongoDB indexes required by the <see cref="PumpState"/> collection, including a unique index on <see cref="PumpState.DeviceId"/>, a compound index on <see cref="PumpState.DeviceId"/> and <see cref="PumpState.LastUpdated"/> for time-based queries, and an index on <see cref="PumpState.PatientId"/> for patient-scoped lookups.
/// </summary>
/// <!-- aidoc:v1 sig=4955da2 body=fd5fa60 -->
public override async Task CreateIndexes()
{
var indexModels = new List<CreateIndexModel<PumpState>>
{
// Clave única del snapshot
new CreateIndexModel<PumpState>(
Builders<PumpState>.IndexKeys.Ascending(x => x.DeviceId),
new CreateIndexOptions { Unique = true, Name = "ux_deviceId" }),
// Consultas por DeviceId + actualización temporal
new CreateIndexModel<PumpState>(
Builders<PumpState>.IndexKeys
.Ascending(x => x.DeviceId)
.Descending(x => x.LastUpdated),
new CreateIndexOptions { Name = "ix_deviceId_lastUpdated" }),
// indexado por PatientId
new CreateIndexModel<PumpState>(
Builders<PumpState>.IndexKeys.Ascending(x => x.PatientId),
new CreateIndexOptions { Name = "ix_patientId" })
};
await Collection.Indexes.CreateManyAsync(indexModels);
}
/// <summary>
/// Retrieves the pump state associated with the specified device identifier, returning null when no matching record exists.
/// </summary>
/// <param name="deviceId">The unique identifier of the device whose pump state should be looked up.</param>
/// <returns>A <see cref="PumpState"/> instance if a matching record is found; otherwise, null.</returns>
/// <!-- aidoc:v1 sig=bab429b body=ea4c529 -->
public async Task<PumpState?> FindByDeviceIdAsync(string deviceId)
{
return await Collection.Find(x => x.DeviceId == deviceId).FirstOrDefaultAsync();
}
/// <summary>
/// Inserts the specified <see cref="PumpState"/> or updates the existing one identified by its <c>DeviceId</c>. If a matching record is found, its identifier is reused; otherwise a new identifier is generated when the provided one is empty.
/// </summary>
/// <param name="state">The pump state to persist. Its <c>Id</c> is preserved or assigned based on whether a record with the same <c>DeviceId</c> already exists.</param>
/// <!-- aidoc:v1 sig=5ce0824 body=9517005 -->
public async Task UpsertAsync(PumpState state)
{
var existing = await Collection
.Find(x => x.DeviceId == state.DeviceId)
.FirstOrDefaultAsync();
if (existing != null)
state.Id = existing.Id;
else
if (state.Id == ObjectId.Empty)
state.Id = ObjectId.GenerateNewId();
await Collection.ReplaceOneAsync(
x => x.DeviceId == state.DeviceId,
state,
new ReplaceOptions { IsUpsert = true });
}
/// <summary>
/// Asynchronously retrieves all <see cref="PumpState"/> records from the data store.
/// </summary>
/// <returns>A task that represents the asynchronous operation, containing an <see cref="IEnumerable{T}"/> of all <see cref="PumpState"/> records; an empty collection is returned if no records exist.</returns>
/// <!-- aidoc:v1 sig=22c3173 body=c62f88b -->
public async Task<IEnumerable<PumpState>> GetAllAsync()
{
return await Collection.Find(Builders<PumpState>.Filter.Empty).ToListAsync();
}
}
}