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:
@@ -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")]
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface IBankSyncService
|
||||
Task<SyncConnectionResponse> CompletePlaidLinkAsync(Guid userId, CreatePlaidConnectionRequest request);
|
||||
|
||||
// SimpleFIN flow
|
||||
Task<SyncConnectionResponse> CreateSimpleFinConnectionAsync(Guid userId, CreateSimpleFinConnectionRequest request);
|
||||
Task<List<SyncConnectionResponse>> CreateSimpleFinConnectionAsync(Guid userId, CreateSimpleFinConnectionRequest request);
|
||||
|
||||
// Account linking
|
||||
Task<List<DiscoveredAccountResponse>> DiscoverAccountsAsync(Guid userId, Guid connectionId);
|
||||
|
||||
Reference in New Issue
Block a user