feat: add Plaid transaction handling and async queue processing
- introduced new migration to add Cursor column to AccountMetadata. - updated AppDbContext model snapshot to reflect changes in the database schema. - implemented async queue processing with ChannelAsyncQueue and AsyncQueueHostedService. - created Plaid transaction handlers for added, modified, and removed transactions. - developed PlaidTransactionService and PlaidTransactionSyncer for syncing transactions. - added SyncUpdatesProcessor to handle sync updates from Plaid. - updated tests to accommodate changes in institution and account metadata handling.
This commit is contained in:
@@ -172,7 +172,7 @@ public class AddTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
await context.AddAsync(user, ct);
|
||||
|
||||
var encryptedAccessToken = await encryptor.EncryptAsyncFor(user, "accessToken", ct);
|
||||
var plaidMetadata = PlaidMetadata.From("alreadyExists", "Some Bank", encryptedAccessToken);
|
||||
var plaidMetadata = PlaidInstitutionMetadata.From("alreadyExists", "Some Bank", encryptedAccessToken);
|
||||
var institution = Institution.From("Some Bank", plaidMetadata);
|
||||
|
||||
await context.AddAsync(institution, ct);
|
||||
@@ -192,7 +192,7 @@ public class AddTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
.WithUserId(user.Id)
|
||||
.WithBody(new
|
||||
{
|
||||
plaidInstitutionId = ((PlaidMetadata)institution.Metadata!).PlaidId,
|
||||
plaidInstitutionId = ((PlaidInstitutionMetadata)institution.Metadata!).PlaidId,
|
||||
plaidAccountId = ((PlaidAccountMetadata)account.Metadata!).PlaidId,
|
||||
plaidAccountName = ((PlaidAccountMetadata)account.Metadata).PlaidName,
|
||||
accountCurrencyCode = "USD",
|
||||
@@ -217,7 +217,7 @@ public class AddTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
var user = User.From("User1", passwordHasher.Hash("@Password1"), userEncryptionKey);
|
||||
|
||||
var encryptedAccessToken = await encryptor.EncryptAsyncFor(user, "accessToken", ct);
|
||||
var plaidMetadata = PlaidMetadata.From("id", "Some Bank", encryptedAccessToken);
|
||||
var plaidMetadata = PlaidInstitutionMetadata.From("id", "Some Bank", encryptedAccessToken);
|
||||
var institution = Institution.From("Some Bank", plaidMetadata);
|
||||
|
||||
user.AddInstitution(institution);
|
||||
@@ -237,7 +237,7 @@ public class AddTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
.WithUserId(user.Id)
|
||||
.WithBody(new
|
||||
{
|
||||
plaidInstitutionId = ((PlaidMetadata)institution.Metadata!).PlaidId,
|
||||
plaidInstitutionId = ((PlaidInstitutionMetadata)institution.Metadata!).PlaidId,
|
||||
plaidAccountId = newAccountId,
|
||||
plaidAccountName = newAccountName,
|
||||
accountCurrentBalance = expectedBalance,
|
||||
|
||||
@@ -101,7 +101,7 @@ public class ConnectTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
var user = User.From("User1", passwordHasher.Hash("@Password1"), userEncryptionKey);
|
||||
|
||||
var encryptedAccessToken = await encryptor.EncryptAsyncFor(user, "accessToken", ct);
|
||||
var plaidMetadata = PlaidMetadata.From("alreadyExists", "Some Bank", encryptedAccessToken);
|
||||
var plaidMetadata = PlaidInstitutionMetadata.From("alreadyExists", "Some Bank", encryptedAccessToken);
|
||||
var institution = Institution.From("Some Bank", plaidMetadata);
|
||||
|
||||
user.AddInstitution(institution);
|
||||
@@ -117,7 +117,7 @@ public class ConnectTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
.WithBody(new
|
||||
{
|
||||
publicToken = "token",
|
||||
plaidInstitutionId = ((PlaidMetadata)institution.Metadata!).PlaidId,
|
||||
plaidInstitutionId = ((PlaidInstitutionMetadata)institution.Metadata!).PlaidId,
|
||||
})
|
||||
.Build();
|
||||
|
||||
@@ -179,7 +179,7 @@ public class ConnectTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
var institution = updatedUser.Institutions.First();
|
||||
institution.Name.Should().NotBeNullOrEmpty();
|
||||
|
||||
var metadata = institution.Metadata.As<PlaidMetadata>();
|
||||
var metadata = institution.Metadata.As<PlaidInstitutionMetadata>();
|
||||
metadata.PlaidId.Should().Be(plaidInstitutionId);
|
||||
metadata.PlaidName.Should().Be(institution.Name);
|
||||
metadata.EncryptedAccessToken.Should().NotBeNullOrEmpty();
|
||||
|
||||
@@ -92,7 +92,7 @@ public class GetAvailableTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
AccessToken = exchangeTokenResponse.AccessToken,
|
||||
});
|
||||
var encryptedAccessToken = await encryptor.EncryptAsyncFor(user, exchangeTokenResponse.AccessToken, ct);
|
||||
var institutionMetadata = PlaidMetadata.From(institutionId, "Some Bank", encryptedAccessToken);
|
||||
var institutionMetadata = PlaidInstitutionMetadata.From(institutionId, "Some Bank", encryptedAccessToken);
|
||||
var institution = Institution.From("Some Bank", institutionMetadata);
|
||||
|
||||
user.AddInstitution(institution);
|
||||
|
||||
@@ -45,7 +45,7 @@ public class GetTests(TestApi testApi) : IntegrationTest(testApi)
|
||||
var user = User.From("User1", passwordHasher.Hash("@Password1"), userEncryptionKey);
|
||||
|
||||
var encryptedAccessToken = await encryptor.EncryptAsyncFor(user, "accessToken", ct);
|
||||
var plaidMetadata = PlaidMetadata.From("alreadyExists", "Some Bank", encryptedAccessToken);
|
||||
var plaidMetadata = PlaidInstitutionMetadata.From("alreadyExists", "Some Bank", encryptedAccessToken);
|
||||
var institution = Institution.From("Some Bank", plaidMetadata);
|
||||
|
||||
user.AddInstitution(institution);
|
||||
|
||||
Reference in New Issue
Block a user