Skip to main content

Command Palette

Search for a command to run...

Designing a Budgeting App

Building the backend and database

Updated
5 min read
Designing a Budgeting App

In the last article we spoke about why you need a financial application. We dived into the features required and why we’d build one. In this article I will share with you how I designed Yafa. This will focus on the backend choices and how I designed the database models as well.

Before we get started lets quickly go over the features that we absolutely need in the application.

  1. A budgeting application needs to keep track of transactions. It needs to check for expenses and income.

  2. These transactions need labels of some kind. How do we know if income is from salary or is it from rent. This is why we should be able to categorise transactions. Transactions can belong to multiple categories as well. Consequently we should have categories.

  3. Now that we know how money is flowing we need to track where its going to. We have accounts for this purpose. We have bank accounts which store money and where want to track expenses to. We also have expense accounts, eg. loan accounts and credit cards. In these cases do we want to track the transactions or do we want to track payments. For a budgeting app we want to see credit card transactions, but we want to track payments as expenses as we only pay when we pay the credit card.

  4. Now that we have an underlying idea of the financial side of the application, we need to decide on the more generic features of the application. We need user models, groups, so we can have multiple budgets etc.

Before we can commit to backend frameworks and database models and the like we need to understand the flow if data. This will help shape both the UI and also the server calls and database models that need to be built.

The actions the user can take are:

  1. User creates account.

  2. User logs in.

  3. User requests support

  4. User updates settings.

  5. User creates account.

  6. User creates category.

  7. User creates transaction.

There are only 7 actions that need to be implemented for the Minimum Viable Product and only 3 that are part of the “finance” portion of the application.

Choosing a Framework

Now that we have described the app and the operations of the app, lets look at what framework to use. Modern day development uses react on top of nextjs or other JS framework that spans both front end and back end. The problem for me is that I want to deploy quickly and I don’t have time to learn a framework. I have a pretty strong background in python and also raw JS. Further to this my sql is intermediate at best if I were to be generous.

For me this means choosing a python web framework and the two that I have used in the past are Django and Flask. I have no interest in implementing users or building everything from scratch. Django does a lot of things automatically and its batteries included method is what I want to use. It provides an administration page to manage all the database models, as well as user models that can be used for our own user management. Further by using groups we can solve the groups issue as well.

Database & Models

Django also allows us to build database models, that can be deployed on pretty much any relational db engine. For production postgres is the obvious choice. Its open source well supported and scales relatively easily. We know that Django implements models directly in the framework itself. This actually allows us to abstract away many to many relationships as well, making model development quick and easy.

Category Model

The category model is the simplest of all the models. All we need is name and a description. There is nothing else required right at this moment.

Account Model

The account model should contain a name and description like the categories. It should also contain the type of account. Is it an expense account like a credit card or is it a normal account like a bank account. Finally it should contain a balance figure. By having a balance number it avoids us having to pull every single transaction from all history to calculate the balance.

Transactions Model

The transaction model is the most complex. It requires:

  • The transaction date

  • A name

  • A description

  • A foreign key to the account to which the transaction is.

  • A foreign key to the user who created it

  • A Many to Many relationship with all the categories to which its associated. (A category can be associated with many transactions, and a transaction can be associated with many categories).

  • The amount of the transaction and if its an income or expense. In my case I specified that this should be two seperate fields so a transaction could contain both income and expense at the sam time. Further by doing this we can avoid signed numbers as well. Rather we can use the most basic type an unsigned int to represent value.

    • With money calculations we need to use the integer or big integer fields to store or validate date. The reason for this is quite simple, floats are inaccurate and poor representations of money. See here for a longer discussion of the topic.

    • For our purposes storing in cents makes the most sense as it doesn’t need that much precision.

Conclusion

We’ll leave it here for today, over the next set of articles we’ll look at building out the application on one thread and look at designing the fundamental features of the budgeting application. Sign up to my newsletter so that you can follow along.