using MongoDB.Bson; using MongoDB.Driver; namespace StellaOps.Graph.Indexer.Incremental; public sealed class MongoIdempotencyStore : IIdempotencyStore { private readonly IMongoCollection _collection; public MongoIdempotencyStore(IMongoDatabase database, MongoIdempotencyStoreOptions? options = null) { ArgumentNullException.ThrowIfNull(database); var resolved = options ?? new MongoIdempotencyStoreOptions(); _collection = database.GetCollection(resolved.CollectionName); } public async Task HasSeenAsync(string sequenceToken, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var filter = Builders.Filter.Eq("sequence_token", sequenceToken); return await _collection.Find(filter).AnyAsync(cancellationToken).ConfigureAwait(false); } public async Task MarkSeenAsync(string sequenceToken, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var filter = Builders.Filter.Eq("sequence_token", sequenceToken); var update = Builders.Update.Set("sequence_token", sequenceToken) .SetOnInsert("recorded_at", DateTimeOffset.UtcNow.UtcDateTime); await _collection.UpdateOneAsync(filter, update, new UpdateOptions { IsUpsert = true }, cancellationToken) .ConfigureAwait(false); } }