Giter Club home page Giter Club logo

fundraiser-tracker's Introduction

Help Ukraine πŸ‡ΊπŸ‡¦

I've joing the huge volunteering forces of Ukraine to help our Armed Forces win the war agains russian fascists. I conduct online streams on Youtube where I teach Java and it's technologies. All streams are charitable and all raised funds go to buy different equipment for Ukrainian soldiers. I announce all streams on my Youtube channel and later put demonstration code here in repositories.

You can πŸ“Ή get access to online streams, 🀝 support me financially, and πŸ’ͺ help Armed Forces of Ukraine through my volunteering activities by buying me a coffee β˜•: https://www.buymeacoffee.com/ytkach

Thank you in advance for your support! Π‘Π»Π°Π²Π° Π£ΠΊΡ€Π°Ρ—Π½Ρ–! πŸ‡ΊπŸ‡¦

Help Ukraine

GitHub Stats

YuriyTkach's GitHub stats

Totally: wakatime Β  | Β  Last year:

YuriyTkach's wakatime stats

fundraiser-tracker's People

Contributors

actions-user avatar andrycreator avatar dependabot[bot] avatar sweep-ai[bot] avatar yuriytkach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

andrycreator

fundraiser-tracker's Issues

Use AWS SSM instead of Secrets Manager

Since we're storing simple secrets without rotating or managing them, we can use AWS SystemsManager property store.
The main reason - AWS SSM is free to use for our simple secrets. And the SecretsManager is $0.04 per month :)

Notify for debit transaction in Privatbank/Mono account

When we see a debit (money out) transaction in either Privatbank statement (type is D) or Monobank (negative amount), then we can notify somehow about that, as it can lead to potential issues. Notification can be via slack channel, for example, or Slack private message (which is better). Email works as well, if needed.

Migrate to Java 17

Migrate to Java 17, updated github actions and pom.xml file accordingly

Use aws sdk v2 library for dynamodb

Currently, we import aws sdk v1 library for dynamodb with test scope because we use it in tests to do direct calls to dynamodb without quarkus involved.

Let's move to sdk v2

Race condition with fund update

If two http requests come to track donation simultaneously it can start 2 lambda functions in parallel. Then we'll have a race condition in updating fund total - both lambdas will read the current fund total, then add a sum and then write. This can lead to one write overriding the other. We need to resolve that with DynamoDB conditional writes.

We could have used sqs to publish event there and then process them one by one, but that will require to have SQS. If we're still OK and within the processing time limit from Monobank to perform conditional write, then that could be easier to implement.

Add sorting and pagination for list donations endpoint

For fund list REST endpoint let's add sort ASC/DESC query param that will allow to return sorted entries by donation date. Default is DESC.
Also, let's add page and size query params that will allow to return paginated items.

Disable/Enable fund commands

Add command to disable fund that should lead to the following outcomes:

  • cannot track donation - should respond with error that fund is disabled
  • when viewing all funds, disabled funds should show at the bottom
  • when returning fund status and list of funders it should set browser cache to 1 month (configurable)

Obviously, since we will have command to disable fund, we should also have command to enable fund :)

Refactor: Store all donations for all funds in a single table

The single table design is likely more appropriate. Here's why:

  • Moderate Data Volume: The number of records per fund is not so large that it would necessitate separate tables for performance reasons.
  • Temporary Funds: The temporary nature of funds means that the number of active tables would continually grow, increasing management overhead.
  • Access Patterns: Most queries are for the current fund, which can be efficiently handled with a GSI (Global Secondary Index).
  • Simplicity: A single table is simpler to manage, and you can use GSIs to efficiently query for donations related to a specific fund.

Arguments for Separate Tables (good arguments, but something that we don't need):

  • Isolation: Each fund is completely isolated from the others. This can simplify some aspects of data management, such as access control, backup, and deletion.
  • Schema Flexibility: If different funds might have slightly different data requirements, separate tables can accommodate these differences more easily.

Since we already have separate tables, we would need to write a script that first populates that newly created table with data from existing donations tables. We have switch in lambda to single donation's table, deploy it and then run the script. For a short time list of donators won't be visible, which is fine.

Sweep: When tracking donation, update fund with condition to check expected current fund total amount to avoid race conditions

Details

When donation is tracked the fund's total amount is updated. Currently it simply adds donation amount to fund and then saves the fund. When saving we should use DynamoDB's conditional write to verify that current fund amount is what it was before added the donation amount. If condition fails, then we should retry at most 3 times with exponential backoff. On every retry we should recalculate new fund total based on new total that is present in DB.
Add integration test to check that update does not happen if current fund amount in DynamoDB is not what we expect.
Use 'final' keyword for local variables and function parameters.
Validate for unused imports and remove those.
Use 2 spaces indentation.

Checklist
  • Modify src/main/java/com/yuriytkach/tracker/fundraiser/service/DonationTracker.java βœ“ 24dccca Edit
  • Running GitHub Actions for src/main/java/com/yuriytkach/tracker/fundraiser/service/DonationTracker.java βœ“ Edit
  • Modify src/main/java/com/yuriytkach/tracker/fundraiser/service/dynamodb/DynamoDbFundStorageClient.java βœ“ fb38d2e Edit
  • Running GitHub Actions for src/main/java/com/yuriytkach/tracker/fundraiser/service/dynamodb/DynamoDbFundStorageClient.java βœ“ Edit
  • Create src/test/java/com/yuriytkach/tracker/fundraiser/service/DonationTrackerIntegrationTest.java βœ“ 2b3dd09 Edit
  • Running GitHub Actions for src/test/java/com/yuriytkach/tracker/fundraiser/service/DonationTrackerIntegrationTest.java βœ“ Edit

Return only active funds in `list` command

The list command from Slack returns all funds. Since number of funds can be huge, let's return only active (enabled) funds. And allow to view all with the help of -all parameter.

Use AWS Secrets Manager to store keys/tokens

Currently, the slack token is provided in Environment variable.
Also, after we add support for Privatbank statements upload we would need to store token somewhere.

The AWS Secrets Manager is a good place to store secrets there. Also, quarkus has support for it!

Sweep: Race condition with fund update

Details

If two http requests come to track donation simultaneously it can start 2 lambda functions in parallel. Then we'll have a race condition in updating fund total - both lambdas will read the current fund total, then add a sum and then write. This can lead to one write overriding the other. We need to resolve that with DynamoDB conditional writes.

Checklist
  • Modify src/main/java/com/yuriytkach/tracker/fundraiser/service/dynamodb/DynamoDbDonationClientDonation.java βœ“ ceebaf0 Edit
  • Running GitHub Actions for src/main/java/com/yuriytkach/tracker/fundraiser/service/dynamodb/DynamoDbDonationClientDonation.java βœ“ Edit
  • Modify src/main/java/com/yuriytkach/tracker/fundraiser/service/TrackService.java βœ“ 0a80a91 Edit
  • Running GitHub Actions for src/main/java/com/yuriytkach/tracker/fundraiser/service/TrackService.java βœ“ Edit

Add ability to track fund spending

Add support with special slack command to be able to track spending of fund.

Command to support:
spend 1500 uah 2022-05-29 11:14 "Buy the drone", where

  • spend - command name (required)
  • 1500 - amount (required)
  • uah - currency (optional, use fund's currency by default)
  • 2022-05-29 - date (optional, use today's date by default)
  • 11:14 - time (optional, use current time by default)
  • "Buy the drone" - description (optional, put something by default)

Tracking of spending should go into separate table.

Add field to Fund object called spent to track total amount that was spent. Update that field each time a spending is recorded.

Return total spent amount when processing list command.

Return all spending records together with donations records when processing list <fundname> command.

Edit fund command

Add support for the edit fund command.
It should allow to edit fund data, like goal, currency, description, color.
If currency is changed, the raised field should be converted to new currency.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.