Building A Financial Planner for Couples

Thomas Oh
8 min readOct 10, 2020

Building A Financial Planner for Couples

Screenshot of the Financial Planner App — Sticky Note Page

The Technical Challenge

The idea behind the project was a simple one — to build a web-app that would allow couples to have an integrated overview of their finances. As I began to scope out the project, I started to get a little concerned about some of the technical challenges that I would have to overcome. For one, I would need to build some logic that allows two users to log into a single account. Another huge hurdle I would have to overcome is figuring out the Google Drive API .

But heck, I decided to be a lot more positive about it — these were exciting challenges! I would probably learn loads from the process, and I should just dive in.

In terms of the tech stack I used, I took a pretty simple approach. I used the usual Express and Node combination on the back-end, with the “express-react-views” package to serve up pages to the client. For the database, I used PostgreSQL which made a good deal of sense for the sticky notes (explained below). Check out the github if you want more details!

Github!

Live Site!

Login Logic

Login / User Switch
Registration / User Creation

As you can see from the pictures, the idea is to simply create another layer after the usual registration / login form that would take into account the fact that two individual humans will be sharing one account.

So I took the usual MVC framework that I was familiar with to ensure this additional layer was taken into account.

  • Views — for registration, I simply needed to create an additional jsx file that would represent the “create users” page. This would be a separate view from the initial sign-up page. Once an account was registered though, no separate view would be needed; a simple section in the navbar of the main page would be sufficient to toggle between users
  • Routes + two controllers — the routes were simple, and mapped cleanly to the controller. You can find the source code for those components here (routes, controller(accounts), controller(users)). I think the key thing to note is the series of cookies I used to keep track of a user once they had logged in. The necessary information is taken from the database (through the modelRequest object), which is then used to set the relevant cookies (especially the information on partners!)
const modelRequest = await db.accounts.verifyLogin(req.body.accountname, req.body.password);if (modelRequest.loginSuccess) {            
res.cookie('loggedin', modelRequest.currentSessionCookie)
res.cookie('accountname', modelRequest.queryResult.accountname)
res.cookie('account_id', modelRequest.queryResult.id)
res.cookie('currentpartner', modelRequest.partnerA)
res.cookie('partnerA', modelRequest.partnerA)
res.cookie('partnerB', modelRequest.partnerB)
res.redirect('/')
}
  • Model — The last bit is the model. I think it’s most useful to talk about the database I set up here. As mentioned, this is an SQL database, and the point to to be aware of here is that I created separate SQL tables for “accounts” and “users”. The former would contain basic information common to both partners (e.g. account name, password), but the latter would contain information unique to each individual (e.g. username, income). Do note that each entry in the users table would have to have a foreign key of “account_id” to ensure it referred to the same account.

Illustration of different SQL queries used in the model

let queryString = "INSERT INTO accounts (accountname, password) VALUES ($1, $2) RETURNING *";let queryString = "SELECT * FROM accounts WHERE accountname = $1";let usernameQueryString = "SELECT username FROM users WHERE account_id = $1"let queryString = "INSERT INTO users (account_id, username, income) VALUES ($1, $2, $3) RETURNING *";let queryString = "UPDATE users SET income = $3 WHERE account_id = $1 AND username = $2 RETURNING *";

Takeaways — So in the end I found that this “two user one account” login system wasn’t terribly difficult to build, and I felt a bit silly worrying about it! In all honesty, it just took a little time to break down exactly what I needed to happen for the user, and how to adapt the MVC pattern to take into account the change from a usual login process.

Database Building

Ah sticky notes. Sticky notes, or some kind of to-do app, have always been a staple of programming projects. Surprisingly though, it seemed to make sense in this web app for couples. One partner could leave a message for the other about their finances in a fairly convenient way, instead of having it stored somewhere deep in a WhatsApp chat history.

Creating a sticky note on the front-end is easy — there is literally a textarea html element that you can customize and style to your heart’s content. You can then make the textarea element draggable through a variety of ways — there are a ton of guides on this so I won’t go into it.

For me, the learning experience was on ensuring the data persists even after you log out and log back in, to truly turn the sticky notes into a CRUD application. Hence, the first step is breaking down the relevant data that forms a sticky note

As you can see, you only need to store the following categories of information — (1)x coord, (2) y coords, (3) height, (4) width, (5) content, and (6) the partner who wrote the sticky notes. There were the only unique parts of any sticky note on the board. Everything else about the note, especially the styling, could be standardized.

Once I broke it down this way, the entire process became so much easier! I could setup the SQL table, code out the MVC framework to pass the data back and forth, and eventually write the AJAX requests as well. These were the main components to my final product:

  • GET requests — on signing in, the client would send a get request to pull all the relevant sticky notes for the relevant account
  • POST requests — a ‘save’ button would update the database with any and all changes to the sticky notes
  • Front End Editing — An “Add New Note” Button on the front-end and an “X” button at the top right corner of each sticky note, allowed a user to manipulate the sticky notes as they appeared on the page. These buttons would not change anything in the database until the “save” button was clicked.

Takeaway — Building this section of the project helped me realise how useful SQL databases can be. Since SQL databases can store a whole range of data types including strings, it had the potential to solve the data persistence needs of many applications. I think I had the tendency to think of SQL as a finance tool, or a tool that was mostly used for extracting integers or floats in a very “math-y” setting.

Google Drive Integration

The last and the most challenging part of this project I had to build was the Google Drive integration. The rationale behind this part was simple — I figured most people would store important finance documents in some sort of cloud storage, and allowing couples to have access to these documents in my app made a great deal of sense.

The actual logic flow of this was not terribly complicated. It required:

  • A form in the view to allow a user to upload documents, with a post request containing the document to be sent to the backend
<form method="POST" action="/upload" enctype="multipart/form-data" id="upload-form" />
  • A controller to receive the post request and to handle the eventual upload to a user’s google drive (see upload.js)

Of course, life is never that easy, and as I was building these components out, I realised that there was a significant amount that I needed to learn

  • OAuth 2.0
  • API Keys and Google Developer Console
  • Google Drive API

I won’t go into the details behind these things because there are already a million other tutorials out there that guide you through it. However, I tell people not to be afraid of these topics. They are actually relatively easy to understand if you take the time and be patient with learning.

Here are some of the resources I used to figure out these components.

After pouring through the resources above, I managed to hook up my web-app with a google drive integration! From the user’s perspective, all he would have to do is click “authorize” first, which would lead him to a very familiar Google page, and choose the google account he wishes to integrate with. Thereafter, the upload functionality is available to him!

Takeaway — This was the most challenging portion of the project, particularly because I didn’t realise I had to understand OAuth 2.0 before being able to use Google Drive upload. From prior experience, I knew that some of the other google drive apis did not really require any form of authentication (e.g. maps). But nevertheless, it was fun to learn! There are pretty solid resources online to tap on.

Conclusion

A few things really stood out to me during this project!

  • Break down what you need to learn into smaller chunks There is a traditional engineering emphasis on breaking down big hairy problems into smaller, more manageable chunks. I would argue this approach applies well even when you are just learning big hairy stuff. For the google drive integration in particular, I had the big task of learning how to use Google Drive APIs, and the only way I could manage this was to break it down into smaller subcomponents to learn on a step-by-step basis(e.g. what on earth is OAuth 2.0, how does Google use OAuth 2.0). It was almost as if I was putting together a mini curriculum before I began.
  • SQL databases can do a lot — I touched on this earlier, but it’s worth repeating! SQL databases have the potential to solve a whole range of data persistence needs, and I should not limit its use to “Excel-like” purposes.
  • Find the learning process fun! — To me, coding is awesome for two huge reasons. You get to learn amazing things along the way as you build out the product, and you get the satisfaction when you see it work! It’s important to not forget the first part and only derive satisfaction from achieving functional code. I could never have gotten through this project if I didn’t enjoy learning above Google Drive APIs and OAuth 2.0, mostly because I honestly didn’t see any tangible results in my codebase for quite awhile, at least during the period I was teaching myself these concepts.

Thanks for reading! Feel free to ask me any questions about the code or my process :)

--

--