Update existing SimpleFIN connections on re-connect instead of creating duplicates
When a user re-connects SimpleFIN (e.g. after a key change), match existing connections by institution name and update the access token in-place rather than always creating new SyncConnection records. New linked accounts are added if discovered, existing mappings are preserved. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -191,34 +191,72 @@ public class BankSyncService : IBankSyncService
|
||||
var accounts = await _simpleFin.GetAccountsAsync(config);
|
||||
var encryptedAccessUrl = _encryption.Encrypt(accessUrl);
|
||||
|
||||
// Load existing SimpleFIN connections for this user to avoid duplicates on re-connect
|
||||
var existingConnections = await _db.SyncConnections
|
||||
.Include(c => c.LinkedAccounts)
|
||||
.Where(c => c.UserId == userId && c.Provider == SyncProvider.SimpleFIN)
|
||||
.ToListAsync();
|
||||
|
||||
var groupedByInstitution = accounts.GroupBy(a => a.Institution ?? "SimpleFIN Connection");
|
||||
var connectionIds = new List<Guid>();
|
||||
|
||||
foreach (var group in groupedByInstitution)
|
||||
{
|
||||
var connection = new SyncConnection
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = userId,
|
||||
Provider = SyncProvider.SimpleFIN,
|
||||
InstitutionName = group.Key,
|
||||
EncryptedAccessToken = encryptedAccessUrl
|
||||
};
|
||||
// Check if a connection already exists for this institution
|
||||
var existing = existingConnections.FirstOrDefault(c =>
|
||||
c.InstitutionName == group.Key);
|
||||
|
||||
_db.SyncConnections.Add(connection);
|
||||
connectionIds.Add(connection.Id);
|
||||
|
||||
foreach (var account in group)
|
||||
if (existing != null)
|
||||
{
|
||||
_db.LinkedAccounts.Add(new LinkedAccount
|
||||
// Update the existing connection with the new access token
|
||||
existing.EncryptedAccessToken = encryptedAccessUrl;
|
||||
existing.IsActive = true;
|
||||
existing.UpdatedAt = DateTime.UtcNow;
|
||||
connectionIds.Add(existing.Id);
|
||||
|
||||
// Add any new linked accounts not already tracked
|
||||
foreach (var account in group)
|
||||
{
|
||||
if (!existing.LinkedAccounts.Any(la => la.ExternalAccountId == account.ExternalId))
|
||||
{
|
||||
_db.LinkedAccounts.Add(new LinkedAccount
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
SyncConnectionId = existing.Id,
|
||||
ExternalAccountId = account.ExternalId,
|
||||
ExternalAccountName = account.Name,
|
||||
ExternalAccountType = account.AccountType,
|
||||
LastKnownBalance = account.Balance
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var connection = new SyncConnection
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
SyncConnectionId = connection.Id,
|
||||
ExternalAccountId = account.ExternalId,
|
||||
ExternalAccountName = account.Name,
|
||||
ExternalAccountType = account.AccountType,
|
||||
LastKnownBalance = account.Balance
|
||||
});
|
||||
UserId = userId,
|
||||
Provider = SyncProvider.SimpleFIN,
|
||||
InstitutionName = group.Key,
|
||||
EncryptedAccessToken = encryptedAccessUrl
|
||||
};
|
||||
|
||||
_db.SyncConnections.Add(connection);
|
||||
connectionIds.Add(connection.Id);
|
||||
|
||||
foreach (var account in group)
|
||||
{
|
||||
_db.LinkedAccounts.Add(new LinkedAccount
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
SyncConnectionId = connection.Id,
|
||||
ExternalAccountId = account.ExternalId,
|
||||
ExternalAccountName = account.Name,
|
||||
ExternalAccountType = account.AccountType,
|
||||
LastKnownBalance = account.Balance
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user