This website acts as a personal finance dashboard.
- It allows users to make a profile and pull financial data from all of their Financial Institutions into one place.
- The app itself aggregates balances from all of the user's Accounts, displaying their overall worth (with and without loans).
- It uses graphics to illustrate the breakdown of the user's Financial Institutions and what percentage of their overall wealth is in each.
- Below the dashboard there is an Account-level breakdown of each Financial Institution listed that displays the individual balances based on Account type.
- This was completed in approximately 60 hours as part of Springboard Software Engineering Program.
- Tech Stack
- Database Schema
- Deployment
- Developer
- Features
- Running App Locally
- Testing
- Additional Steps
JavaScript, Axios, HTML5, CSS, Bootstrap, jQuery, GoogleChart.js
Python, Flask, ORM: SQLAlchemy, Jinja2, WTForms, Bcrypt, Cron
Postgres
CashView is deployed on heroku at https://wealth-and-budget.herokuapp.com/
Please feel free to reach out!
User Registration goes through the User model on the backend, user enters desired username, password, phone number, first name, last name, and desired Account type (sandbox or development (more on that later)). All information is required and username must be unique for the model to generate a User instance. Password is run through Bcrypt hashing function where the output is stored in the database.
Login authentication occurs on the User model as well. If a User logs in with correct username/password pair, User authenticate method returns the User instance, if not it returns False.
To reduce barrier of entry of someone trying to experience the App, I integrated a 'Demo User' button on the Login page. This uses JavaScript and jQuery behind the scenes to enter credentials:
- Username: Test_User
- Password: pass_good
NOTE: There is backend logic to protect Test-User from modification or deletion
Once a user is logged in, they will see 'Update Profile' as an option on their navbar and under 'User Options' on the dashboard, there is an 'Update Profile' button a user can click which will lead them to a portal to edit their profile. All of their current information is populated into the input fields of the form. Once they have updated their information to the desired values and enter their password at the bottom to confirm the changes, they can click 'Update' to have their changes made in the database.
Once a user is logged in, they will see an option to 'Delete Profile' under 'User Options'. Once they click this, their User instance will be removed from the database on the back-end and they will be redirected to the welcome page of CashView on the frontend. There is a cascading deletion set up in the database schema so all Financial Institutions, Accounts, and BudgetTrackers will be deleted as well.
Using the Plaid API, a user can securely add their credentials to Plaid's Link interface that is embedded in the dashboard. These credentials are not stored in the any area of CashView at any point. To avoid this being an issue, I made sure users that sign up have the option of having a development Account, which deals with real bank data, or a sandbox Account, which deals with dummy bank Accounts from Plaid. The Demo user experience is a sandbox Account as well.
Once on the dashboard page, a user clicks on 'Link Institution' under 'User Options'.
After the user does this, Plaid's Link interface experience will appear. You will be able to choose your Financial Institution of choice from a list, then enter the required credentials to pull the data into CashView. If you have a development Account, you enter your real credentials, if you have a sandbox Account you enter the information under 'User Options' in the image above (can also be seen at the footer of the Link portal):
- Username: user_good
- Password: pass_good
If the correct information is entered, CashView will go through the Plaid Token exchange process and receive an access_token associated with the specified Financial Institution. Using this access_token, the app makes two further API calls to Plaid:
- To retrieve data on the Financial Institution (called an 'item' in Plaid's vernacular) see Response Fields
- To retrieve data on Accounts held by that Financial Institution see Response Fields
Financial Institution and Account/s instances are created in the CashView database then json data is sent to the dashboard to create the required HTML to represent the instances. If a user already has Financial Institutions and Accounts associated with their User instance, Jinja2 templates create the required HTML upon page load.
(Financial Institution in CashView Dashboard)

(Same Financial Institution in CashView Dashboard with some Accounts deleted and view uncollapsed)

NOTE: Due to the fact I am using the free tier of Plaid's API, API calls for Account retrieval take upwards of 30 seconds. Because this is deployed on Heroku and their dynos timeout after a 30 second wait the developer User Account type will not allow you to connect your actual Accounts on the heroku deployment of CashView. However, it does work on local deployment, even though you have to wait ~40 seconds (what I benchmarked). I checked with Plaid's support team and they confirmed that the free tier of their API service would likely have longer wait times while the premium tier would see 2-3 second waits.
(Confirmation of long API wait times for free tier of service)

For each Financial Institution on the dashboard, there is an 'Update' icon. This is for manual refreshing of Account balances. This will make a call to the back-end to grab all the Plaid Account IDs associated with that Financial Institution in the CashView database and get the most up-to-date balance information for these Accounts from Plaid. This data will be sent back to the front-end and the HTML will be updated to reflect the most recent balances.
For each Financial Institution and Account (uncollapsed) on the dashboard, there is a 'Delete' icon. This is for deletion of desired Accounts you do not want to track and Financial Institutions, respectively. This will make a call to the back-end to delete the desired Account or Financial Institution in the CashView database. Upon deletion, your overall wealth and balance information at the Financial Institution level will change (if you delete Accounts from a Financial Institution). Updated roll-up balance data will be sent back to the front-end and the HTML will be updated to reflect the most recent balances.
(Financial Institution deletion: Top right of 'Chase', red deletion button icon)

(Account deletion: Top right of 'Plaid Checking' red deletion button icon)

If an Account is elegible (is of type 'credit' or sub-type 'checking'), it will have a 'Create BudgetTracker' button displayed at the bottom. Clicking this will bring the user to a BudgetTracker creation form for that particular Account where they can enter their desired 'Monthly Budget Threshold' amount (must be greater than $0) and their desired Notification Frequency that they would like to receive text notifications at (must be between 1 and 15 days). These texts updates will occur at frequency multiples of the day frequency they enter (e.g. if they enter 2, they would receive a text notification every other day). This is enabled by a script that runs once each day to:
- Update the most recent 'amount_spent' on BudgetTrackers (and all Accounts in the system)
- See if the 'next_notification_date' on the BudgetTracker is equal to the current date
- If it is not, it does nothing
- If it is, it:
- fires off a text notification with the 'amount_spent' compared to the budget threshold
- updates the 'next_notification_date' using the 'notification_frequency' the user set to add the number of days to the Datetime Object in the database for next notification
The BudgetTracker will then appear on the Dashboard under the associated Account displaying all information ('budget_threshold', 'amount_spent', 'notification_frequency', 'next_notification_date') which is updated by the script that runs daily.
NOTE: If the User's 'account_type' is 'sandbox', they are ineligible for text notifications. I am also running the freemium of Twilio, so for the 'development' User 'account_type', unless your cellphone number is verified under my Twilio Account for the web app, you would not receive a text message. If you would like to use the text notification feature, you would need to get your own API keys for Plaid and Twilio and run this app locally.
Once a BudgetTracker is created, it will appear on the Dashboard where it can be edited or deleted. To edit, click the 'edit' icon at the bottom of the BudgetTracker. This will direct the User to the Update BudgetTracker form where the user can modify the BudgetTracker's 'budget_threshold' and/or the 'notification_frequency'. These values will be updated in the database and the new values will be reflected on the Dashboard.
(BudgetTracker Update: Bottom of BudgetTracker blue 'edit' icon)

To delete a BudgetTracker, navigate to the associated Account on the Dashboard where it lives. At the bottom of the BudgetTracker Card, click on the 'delete' icon. The BudgetTracker will be removed from the database and the HTML will return the 'Create BudgetTracker' button under the Account.
(BudgetTracker Delete: Bottom of BudgetTracker red 'delete' icon)

(BudgetTracker Create Button returned)

The dashboard is designed to be a quick view of the aggregate of all of a User's Financial Institutions. The total holdings, both with and without loans are displayed in the top left of the dashboard. The User Model has a method that runs through all of the User instance's Financial Institutions, summing their dollar totals, with a boolean input to signify whether or not to return the sum with loans included (loans are subtracted from the total as they are a dollar amount owed). Financial Institutions have a similar method that allows them to run through all of their Accounts and provide a dollar sum with or without loans. Both of these values are displayed and color coded (green signifies a positive balance, grey means a $0 balance, red is a negative balance).
To the right of the dollar view in the dashboard is a pie chart that shows a percentage breakdown of how Financial Institution sums (without loans) represent a User's total wealth. This utilizes Google Charts.
As a User deletes Financial Institutions and/or Accounts to track, the Dashboard will update on the static page to reflect the changes.
- Python
- PostgresSQL
- pip
Retrieve free API keys from:
-
Clone the repository:
git clone https://github.com/bbeckenb/Wealth_and_Budget_App.git
-
Change Directory to the project:
cd Wealth_and_Budget_App
-
Create and Activate Python Virtual Environment:
python3 -m venv venvsource venv/bin/activate
-
Install requirements:
pip install -r requirements.txt
-
Set up local database:
createdb wealth_and_budget_db
-
Set up .env file:
touch .env
-
Add the following fields and enter your information (Requires API key retrieval step) where it says YOUR_INFO
PLAID_CLIENT_ID=YOUR_INFO PLAID_SECRET=YOUR_INFO PLAID_PRODUCTS=auth,transactions PLAID_COUNTRY_CODES=US,CA TWILIO_Account_SID=YOUR_INFO TWILIO_AUTH_TOKEN=YOUR_INFO TWILIO_NUM=YOUR_INFO SECRET_KEY=YOUR_INFONOTE:
SECRET_KEYcan be whatever you want it to be, you can generate 16 random bytes of hex digits usinghexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/urandomin the command line. -
Job Scheduling:
- Script
scheduled_jobs.pyis scheduled to run on Heroku - If you choose to run this locally, include following code in main
app.pyand follow directions below:- Dependencies to import:
from flask_crontab import Crontab from CronJobs.UFI_jobs import scheduled_daily_refresh_all_Accounts from CronJobs.BudgetTracker_jobs import scheduled_budget_tracker_jobs - Initializations:
crontab = Crontab(app) - CRON schedule function definition:
@crontab.job(minute=0, hour=12) def scheduled_jobs(): scheduled_daily_refresh_all_Accounts(plaid_inst) scheduled_budget_tracker_jobs(plaid_inst, twilio_inst) - Command Line directions:
- CRON Scheduled Jobs For local server
- This will run a job everyday at 12pm UTC: run
flask crontab addin command line to initialize - This will delete the CRON job: run
flask crontab removein command line to remove - These are additional command line commands to navigate jobs
crontab -lto see list of jobscrontab -eto manually edit list of jobs, 'esc' :wq 'enter' to leave list
- Dependencies to import:
- Script
-
Run Flask Application
export FLASK_ENV=productionexport FLASK_RUN_PORT=5000flask run
Testing for Models and Views was written using Python's Unittest Framework . Tests can be seen in test folder.
I built this application as part of SpringBoard's Software Engineering curriculum and put in ~60 hours. If I were to continue developing it, there would be several steps I would take.
I originally planned on having this app be a one-stop-shop to see all of your bank data, house, 401k, Roth IRA, etc., I think this would lead to a more useful application. I would likely go back to Plaid to pull in investment account data (can't without the paid service), and to Zillow for house value, putting bank, house, and investment portfolio on different tabs on the Dashboard. I will come back to this in the future.
I would build out logging functionality to store request/response and errors (separately) that occur in a central location. That way I could see if there are issues that I need to adjust for. I would build out my error handling according to this. I would also Account for when the APIs integrated go down.
I would add an is_admin boolean to the User model and add an Admin portal on the web app itself. It would be much easier to manage data on the app, both test and real.












