fix(infra): don't advance account cursor unless all transactions proceed successfully

This commit is contained in:
Stevan Freeborn
2026-03-09 04:29:01 -05:00
parent 8222698fa8
commit 8d68bfc22a
7 changed files with 212 additions and 72 deletions
@@ -2,32 +2,54 @@ namespace FiscalOS.Infra.Transactions.Plaid;
internal interface IPlaidRemovedTransactionHandler
{
Task HandleAsync(IEnumerable<RemovedTransaction> removed, CancellationToken cancellationToken);
Task<int> HandleAsync(IEnumerable<RemovedTransaction> removed, CancellationToken cancellationToken);
}
internal sealed class PlaidRemovedTransactionHandler : IPlaidRemovedTransactionHandler
{
private readonly AppDbContext _appDbContext;
private readonly ILogger<PlaidRemovedTransactionHandler> _logger;
private PlaidRemovedTransactionHandler(AppDbContext appDbContext)
private PlaidRemovedTransactionHandler(
AppDbContext appDbContext,
ILogger<PlaidRemovedTransactionHandler> logger
)
{
_appDbContext = appDbContext;
_logger = logger;
}
public static PlaidRemovedTransactionHandler From(IServiceProvider serviceProvider)
{
return new(
serviceProvider.GetRequiredService<AppDbContext>()
serviceProvider.GetRequiredService<AppDbContext>(),
serviceProvider.GetRequiredService<ILogger<PlaidRemovedTransactionHandler>>()
);
}
public async Task HandleAsync(IEnumerable<RemovedTransaction> removed, CancellationToken cancellationToken)
public async Task<int> HandleAsync(IEnumerable<RemovedTransaction> removed, CancellationToken cancellationToken)
{
var removedCount = 0;
var removedIdsList = removed.Select(t => t.TransactionId);
await _appDbContext.Transactions
.Where(t => t.Metadata is PlaidTransactionMetadata && removedIdsList.Contains(((PlaidTransactionMetadata)t.Metadata).PlaidId))
.ExecuteDeleteAsync(cancellationToken)
.ConfigureAwait(false);
try
{
removedCount = await _appDbContext.Transactions
.Where(t => t.Metadata is PlaidTransactionMetadata && removedIdsList.Contains(((PlaidTransactionMetadata)t.Metadata).PlaidId))
.ExecuteDeleteAsync(cancellationToken)
.ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(
ex,
"Failed to removed transactions {TransactionIds}",
removedIdsList
);
}
_logger.LogInformation("Removed {RemovedCount} transactions", removedCount);
return removedCount;
}
}