https://github.com/jvillegasd/transaction-logs
Simple bank transaction logs system using Python core and SQLAlchemy
https://github.com/jvillegasd/transaction-logs
python python-core python3 sqlalchemy
Last synced: 2 days ago
JSON representation
Simple bank transaction logs system using Python core and SQLAlchemy
- Host: GitHub
- URL: https://github.com/jvillegasd/transaction-logs
- Owner: jvillegasd
- Created: 2022-12-13T06:13:08.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-12-15T14:00:11.000Z (over 3 years ago)
- Last Synced: 2025-10-12T04:23:00.607Z (8 months ago)
- Topics: python, python-core, python3, sqlalchemy
- Language: Python
- Homepage:
- Size: 68.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Transaction logs
This project consist in create a simple bank transaction system, where users can interact with their transactions and filter them. `Python 3.10` was used for this project.
## Requirements
- As a user I want to be able to login and see the transactions, listed from most recent to least recent.
- As a user I can return my balance as a mathematical result of the executed transactions.
- As a user I want to be able to list the transactions in a range of dates.
- As a user I want to be able to list the transactions by type.
- As a user I want to be able to filter the expenses by merchant.
## System requirements
- You must ensure that a user cannot see the transactions of other users
- There are three types of transactions in this simple system which are deposits, withdrawals and expenses.
- he results of the transactions must be paged being the page size passed as a query parameter, if no parameter present then assume 10 as page size
- You cannot withdraw/waste more money than the account has, therefore negative balances are not allowed.
- If a transaction results in a negative balance, it must be rejected.
- Validate that the date ranges make sense for the transaction filter.
## Data importer
CRUD for transactions is not required, instead, I designed and developed a data importer class that loads seeds in JSON files for the models created for the project. This DataImporter class was designed as a generic way to loads models seeds, so it is reusable.
## Persist data
Loaded seeds are stored in a local `PostgreSQL` database mounted by `Docker` (you can see this service in details in docker compose file), so backend can interact with the data through queries.
## Sessions
In order to maintain sessions for logged users, a simple session provided for Flask was used.
## Libraries
A core rule was to do not use external libraries for the project beyond the framework. So, I chose Flask as Backend micro-framework and SQLAlchemy as ORM library (Unlike Django or FastAPI, Flask lacks of ORM). Schemas, filters, serializers are made from vanilla, my own implementations.
## Documentation
Core functions, method and classes have their own docstring for code documentation. API Postman collection is saved in folder `docs` inside repo.
## Unit testing
Python in-build library `unittest` was used for implement unit tests for this backend. I implemented different test cases for API endpoints and DataImporter in order to cover most cases. Tests inherit from a `BaseCase` class that implement common functions that all tests can use. This class allows unit tests to load models seeds on demand. You can execute tests with the following command:
python3 -m unittest
If you use Docker for run this project, you can run tests with this command:
docker exec transaction-api python3 -m unittest
## Run the project
In order to make easier to run this project in multiple environment, a Docker image and a Docker compose file were created. You can build and run this project with this command:
docker-compose up -d
## Environment variables
On this section, you can see how an Environment vars file looks like:
APP_ENV=dev
PORT=3001
SECRET_KEY=u3gsKSs8QSSdOXkw6nxB9Gq2xuCF8UQ6
POSTGRES_USER=admin
POSTGRES_PASSWORD=admin123
POSTGRES_HOST=transaction-db
POSTGRES_PORT=5432
POSTGRES_DB=transaction-logs-db
## Filtering
A vanilla filtering algorithm was created for handle dynamic filters for ORM queries. For complex filtering such as range comparison, I implemented a bracket notation to accomplish this. On the following table, you will see the available filtering notation. Filters are received as Query parameters!
- For direct filter, use normal query parameter notation, example:
- `GET - /api/transactions?transaction_type=expense`
- For range filtering, you have these operations:
- '[lt]' = 'Lower than'
- '[le]' = 'Lower or equal than'
- '[gt]' = 'Greater than'
- '[ge]' = 'Greater or equal than'
- '[eq]' = 'Equals to'
- Example: `GET - /api/transactions?created_at[ge]=12-15-2022&created_at[le]=12-25-2022`
- PD: Dates have format: `month-day-year`
## Pagination
Pagination is handle via Query parameters using Cursor technique for quick database queries. The cursor is the field `created_at` in timestamp. Example:
GET - /api/transactions?per_page=5&next_cursor=1671112380.617523
You can combine pagination with filters queries!