Step 12: Planning for Transactions

It took 11 articles to get here, but we are finally ready for our last module, transactions. Budgets and accounts are done - for now. While they were mostly independent of one another, transactions is the module that ties everything together. It is where the user will spend most of her time, recording each transaction from one of her accounts and alotting it to a particular budget category. As each log is recorded the application must keep all related information up to date.

Income increases the balance in an account.

A transfer decreases the balance in one account while increasing another.

A payment decreases the balance in an account, and increases the spent amount for a budget category, consequently increasing the spend for that month's budget.

As we plan out this module we must carefully consider whose responsibility it is to make these updates. Should the transactions module directly change the amount spent on a budget category, or should the budgets module provide some sort of API or event system to interface with? How can we ensure that all of our values are consistently updated so that nothing falls out of sync, causing confusion and errors for the user?

The user needs to enter a transaction. Since this is where they will spend most of their time, the interface needs to be seemless, almost effortless. In my experience tracking personal financial transactions is on the same plane as time tracking - if there is any sort of friction at all I easily fall out of the habit. Little annoyances become persistent irritations - choosing a category from a long dropdown list, typing a long business name over and over, constantly moving from keyboard to mouse to click a save button. The user will likely be entering multiple transactions at one time. They don't come to the application every time they make a purchase. They visit it once or twice a week to update everything.

This gives us a good picture of how the interface should operate. We can create a few pseudo-user stories now. The user can

  • add a transaction complete with an account, date, budget category, business name, note, and amount
  • add an expense without having to type the negative sign every time
  • hit enter to save the transaction and move instantly to adding the next transaction
  • view and select from a list of business names they have previously entered
  • select their accounts in the business names in order to easily transfer balances
  • when an existing business is selected, automatically select the budget category used the last time
  • see their account balance and budget values change as they enter transactions

You might be thinking that some of these items don't fall within the Minimum Viable range. I was thinking that too. However, since ease of use is one of our key features I'm going to stick with this list. (Hopefully I don't regret it later!)

With that list of user stories we can break it down into a handful of tasks.

  1. Add a transactions list page showing all transactions. (Later we can let the user filter and restrict this.)
  2. Use a component for each transaction in the list so we can easily edit it later. (We're learning from our past decisions!)
  3. Create an inline add-transaction component.
  4. Store business names in the database to use in the autocomplete dropdown.
  5. Store the most recent budget category used with each business name, and select it automatically if it exists.
  6. Update the budget category for that month when a user adds or edits transaction.
  7. Update the account balance when a user adds or edits a transaction.
  8. Write some sort of sane API for budgets and accounts so that they aren't too tightly coupled with transactions.
  9. If the user selects an account as the business, add an income transaction to that account.
  10. Indicate to the user that they can type 10.53 instead of -$10.53.

That's not so bad. On the surface. Let's take a quick look at what our database structure will look like. This should be familiar by now.

'transactions': {
  'idj384jidi': {
    'id': 'idj384jidi',
    'date': '2017-04-16T22:48:39.330Z',
    'amount': -10.53,
    'note': 'tomato and pepper seedlings',
    'business': 'djinbck8',
    'budget': 'de7ednve',
    'category': 'jcijeojde88',
    'account': 'eorcndl2m'
  }
}

'businesses': {
  'djinbck8': {
    'id': 'djinbck8',
    'name': 'Garden Surplus',
    'lastCategory': 'jcijeojde88'
  }
}

We have hit our first question already. Should transactions reference the budgetCategory or just the original category object? We might later want to let the user view reports for how much they spend in each category over time. The budget object is directly referenced, and the budget category balance will be updated when we enter the transaction. All of this makes category the logical choice.

That's all for planning the transactions module. In the next installment we'll plow through some of the boilerplate code we're used to, and then get into the heart of transactions.


Originally published on


Sign up to receive updates for new articles.
And spam. Definitely lots of spam.