Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove customization from Plaid client code #96

Merged
merged 16 commits into from
Jul 7, 2024
Merged

Conversation

nprzy
Copy link
Contributor

@nprzy nprzy commented Jun 24, 2024

This PR removes most of the customization from the Plaid client code.

Background: I have a few tweaks that I'd like to make that require a few of the newer Transaction fields added by Plaid. The API model that was used to generate the client for this tool does not have those fields. Rather than add the fields in manually I felt that it would be preferable to regenerate the client from scratch using the latest API model. And I'd actually propose going a step further by using the OpenAPI Gradle plugin to generate the Plaid client from scratch during the build process so that none of the generated Plaid client code needs to be checked into git at all.

Most of the changes are well explained by their commit messages. The most significant change here is the dropping of the SortableTransaction interface. This interface was really only used by the transfer-matching logic. I took the opportunity to extract this transfer-matching logic out into its own class.

Assuming that you're OK with these changes, I'll follow with a PR to fully replace the Plaid client with generation of a fresh one on build via the OpenAPI Gradle plugin.

nprzy added 9 commits June 23, 2024 23:15
The PersonalFinanceCategoryEnum existed as custom code that had
been embedded into the generated Plaid client. This extracts the
custom enum and associated logic so that the Plaid client may be
more easily regenerated from the OpenAPI spec.
This getTimestamp method was custom-added on top of the generated
client code. Dropping this usage will make it easier to regenerate
the Plaid client from the OpenAPI spec.
The PlaidTransactionId type alias is custom, added manually to the
generated client code. This reverts PlaidTransactionId usage back
to string to make it easier to regenerate the Plaid client.
Commit a31977f dropped the Transaction-scoped PaymentChannel enums
in favor of the top-level model.PaymentChannel enum. This commit
reverts that change. Although I think that those customizations
make more sense than what the code generator did, reverting this
change will make it easier to auto-generate the Plaid client from
new versions of the OpenAPI spec.
Add a few new Firefly transactions to the input to try and "trick"
the matching logic.
This commit aims to progress us towards eliminating the
SortableTransaction interface, which is only used here in this
transaction matching logic. The new logic uses wrapper classes as
an alternative to adding custom behavior to the generated Plaid
client's Transaction model.
@nprzy
Copy link
Contributor Author

nprzy commented Jun 24, 2024

And here is the follow-up work to generate the Plaid client code as a Gradle build step.

@dvankley
Copy link
Owner

Seems like a lot of work to avoid occasionally updating some API classes... but if you're doing the work then sure, why not.

@dvankley
Copy link
Owner

Did you get any errors when running the openAPI generator or when compiling the output? I don't remember perfectly, but I know I had to manually fix a fair amount of the original generated code (although maybe that was just on the Firefly side).

@nprzy
Copy link
Contributor Author

nprzy commented Jun 25, 2024

Seems like a lot of work to avoid occasionally updating some API classes

Hah yeah, it was a bit more than I had anticipated when I started, but it's done now so ¯_(ツ)_/¯. I've never written Kotlin before so it was a fun learning exercise.

Did you get any errors when running the openAPI generator or when compiling the output? I don't remember perfectly, but I know I had to manually fix a fair amount of the original generated code.

The OpenAPI generator does spit out a few warnings, but it still generates and compiles successfully. I did see a few of your Plaid client customizations (like this and this) and I understand why they were necessary. Those issues were either things that are now fixed in the latest OpenAPI Kotlin templates, fixable via tweaks to the OpenAPI generator configuration, or were configurable externally without needing to modify the generated code. That follow-up PR will have unit tests to validate the correctness of the new generated Plaid client's HTTP interactions.

@dvankley dvankley self-requested a review June 27, 2024 01:22
@bmschwa
Copy link

bmschwa commented Jun 29, 2024

I just ran into an issue that should be solved by this pr. The error (from a citibank account) was: Cannot deserialize value of type 'net.djvk.fireflyPlaidConnector2.api.plaid.models.Products' from String "statements"... Sure enough when I cut the most recent openapi definitions & do a diff of Products.kt, The updated version has quite a few more....

Old Version:
* Values: assets,auth,balance,identity,investments,liabilities,paymentInitiation,identityVerification,transactions,creditDetails,income,incomeVerification,depositSwitch,standingOrders,transfer,employment,recurringTransactions

New Version (commit c793f6d)
* Values: assets,auth,balance,identity,identity_match,investments,investments_auth,liabilities,payment_initiation,identity_verification,transactions,credit_details,income,income_verification,deposit_switch,standing_orders,transfer,employment,recurring_transactions,signal,statements,processor_payments,processor_identity,profile,cra_base_report,cra_income_insights,cra_partner_insights,layer

Copy link
Owner

@dvankley dvankley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good change overall, thanks for the contribution.

Hypocrisy disclaimer (because I definitely didn't do this the first time around): you may want to run the TransactionConverter and TransferMatcher tests with coverage and look at shoring up coverage gaps in the matching logic.

/**
* Represents a single non-transfer transaction, including both the Plaid and the Firefly representation of it.
*/
sealed interface PlaidFireflyTransaction {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A description of the distinction between the subtypes and their intended lifecycle would be useful here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better documentation added in nprzy@a1fc26c

@dvankley
Copy link
Owner

@bmschwa that seems weird to me, as my personal instance is still working fine with a Citi institution, and the connector shouldn't fail on unknown JSON properties anymore as of 3165f7f.
What version of the connector are you running?

@nprzy
Copy link
Contributor Author

nprzy commented Jul 1, 2024

you may want to run the TransactionConverter and TransferMatcher tests with coverage and look at shoring up coverage gaps in the matching logic.

TransferMatcher is 100% covered. TransferConverter has 69% line coverage and 44% branch coverage. I can look at adding another test or two for TransferConverter to give better confidence around the lines that I changed there...

Worked my way through all the feedback (thanks for that). The things that I think are still outstanding for this PR are:

  1. I'd like to take another pass at simplifying how transfers are represented. I'm going to look at adding a Transfer subtype of PlaidFireflyTransaction, and making a few other minor improvements to that interface. This would simplify the output of TransferMatcher and I think make the code a little easier to understand and work with.
  2. Look at improving test coverage as mentioned above.

@bmschwa
Copy link

bmschwa commented Jul 1, 2024

Appreciate the response, @dvankley .

I'm running from the docker... version I see that its version 1.1.1.... but I see a 1.1.2 came out recently so I'll pull and try that.
2024-06-28T23:10:42.858Z INFO 1 --- [ main] .d.f.FireflyPlaidConnector2ApplicationKt : Starting FireflyPlaidConnector2ApplicationKt v1.1.1 using Java 17.0.10 with PID 1 (/workspace/BOOT-INF/classes started by cnb in /workspace)

@bmschwa that seems weird to me, as my personal instance is still working fine with a Citi institution, and the connector shouldn't fail on unknown JSON properties anymore as of 3165f7f. What version of the connector are you running?

Copy link
Owner

@dvankley dvankley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worked my way through all the feedback (thanks for that). The things that I think are still outstanding for this PR are:

  1. I'd like to take another pass at simplifying how transfers are represented. I'm going to look at adding a Transfer subtype of PlaidFireflyTransaction, and making a few other minor improvements to that interface. This would simplify the output of TransferMatcher and I think make the code a little easier to understand and work with.
  2. Look at improving test coverage as mentioned above.
  1. Agreed, but don't sweat it too much.
  2. Same as 1. I definitely think you've improved the overall quality of the code, so don't feel obligated.

Let me know when you're ready either way and I'm good to merge this.

Comment on lines 125 to 126
* This subtype is used when we've received a transaction from Plaid that already has a corresponding transaction
* in Firefly. Note that this is NOT related to
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you didn't finish your thought here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in nprzy@32687b8

@nprzy
Copy link
Contributor Author

nprzy commented Jul 5, 2024

Let me know when you're ready either way and I'm good to merge this.

After these last two commits, I'm good to merge if you are :)

These commits add the promised tests (nprzy@6301282) and Transfer type (nprzy@32687b8). Test coverage of TransactionConverter is up to 92% (199/215) lines and 68% (79/115) branches. And TransactionMatcher remains at 100% line and branch coverage. I did backport the tests locally and run them against your current v1.1.2 to validate no unexpected changes in behavior in this PR. The only new test that failed against v1.1.2 but passed after the changes in this PR was here where v1.1.2 would try to create that highlighted Plaid transaction, but after this PR it's recognized as already created and is omitted from the output.

@dvankley
Copy link
Owner

dvankley commented Jul 7, 2024

Good stuff; let's do it.

@dvankley dvankley merged commit 6848eb1 into dvankley:main Jul 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants