Private
Public Access
1
0

Split SimpleFIN connections by institution

Group discovered SimpleFIN accounts by institution and create a
separate SyncConnection per institution so each bank appears as
its own card in the UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-08 23:26:49 -05:00
parent 54a15cf3cf
commit a2b12d9abd
5 changed files with 46 additions and 29 deletions
@@ -59,7 +59,7 @@ public class BankSyncController : ControllerBase
=> Ok(await _bankSyncService.CompletePlaidLinkAsync(UserId, request));
[HttpPost("simplefin/connect")]
public async Task<ActionResult<SyncConnectionResponse>> ConnectSimpleFin(CreateSimpleFinConnectionRequest request)
public async Task<ActionResult<List<SyncConnectionResponse>>> ConnectSimpleFin(CreateSimpleFinConnectionRequest request)
=> Ok(await _bankSyncService.CreateSimpleFinConnectionAsync(UserId, request));
[HttpGet("connections/{id}/discover-accounts")]
+35 -22
View File
@@ -180,41 +180,54 @@ public class BankSyncService : IBankSyncService
// --- SimpleFIN Flow ---
public async Task<SyncConnectionResponse> CreateSimpleFinConnectionAsync(Guid userId, CreateSimpleFinConnectionRequest request)
public async Task<List<SyncConnectionResponse>> CreateSimpleFinConnectionAsync(Guid userId, CreateSimpleFinConnectionRequest request)
{
var accessUrl = await _simpleFin.ExchangeSetupTokenAsync(request.SetupToken);
var config = new Dictionary<string, string> { ["AccessUrl"] = accessUrl };
var accounts = await _simpleFin.GetAccountsAsync(config);
var institutionName = accounts.FirstOrDefault()?.Institution ?? "SimpleFIN Connection";
var encryptedAccessUrl = _encryption.Encrypt(accessUrl);
var connection = new SyncConnection
var groupedByInstitution = accounts.GroupBy(a => a.Institution ?? "SimpleFIN Connection");
var connectionIds = new List<Guid>();
foreach (var group in groupedByInstitution)
{
Id = Guid.NewGuid(),
UserId = userId,
Provider = SyncProvider.SimpleFIN,
InstitutionName = institutionName,
EncryptedAccessToken = _encryption.Encrypt(accessUrl)
};
_db.SyncConnections.Add(connection);
foreach (var account in accounts)
{
_db.LinkedAccounts.Add(new LinkedAccount
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
});
}
}
await _db.SaveChangesAsync();
return await GetConnectionAsync(userId, connection.Id);
var results = new List<SyncConnectionResponse>();
foreach (var id in connectionIds)
{
results.Add(await GetConnectionAsync(userId, id));
}
return results;
}
// --- Account Linking ---