ActiveGiver Tech: A New Data Model

Our blog focuses on different subjects every week. This week is a look at the way we structure our internal system, with a focus on Tech.

Here’s a General Overview, for you Non Tech-Nerds out there:

When the local elections occurred in November, ActiveGiver went through a quiet, under-the-radar launch with a small number of Seattle politicians. Our main goal was to see the platform in use, get some donations flowing through the system, and iterate on our current model to maximize its use value for both Givers and politicians. At the time of the launch our data model was a Cause-Campaign paradigm. Causes were the policies or issues that the campaign supported and that Givers donated through. A “campaign” referred to the organization that had been established by a particular politician for a particular race. Politicians have to register new campaigns every time they face a new election, so each campaign that we developed was singular and time-restricted. This model was intuitive but ultimately prohibitive to the platform. Because campaigns were geared toward a specific seat, we could only classify politicians based on the position they were seeking, not the one they currently held. Additionally, our back office infrastructure was developed to support state and federal-level congressional elections.  A lack of specification at the local level created situations where positions such as school board member or port commissioner could not be differentiated from one another. Politicians could only have one campaign in our system, so running another campaign in a different election cycle was impossible. We decided to seek a new data model.

After numerous brainstorming sessions, we decided to split Campaigns into three components: Politician, Race, and Campaign. A Politician is now their own entity, able to associate themselves with multiple different campaigns and develop a personal profile with their current position if they are seeking a different elected office. The Race is a description of the position the politician is running for, and can have multiple politicians assigned to it.  Each race expires on the date of its election, maintaining the singularity of each unique race. The Campaign registers both a single Politician and Race and handles financial transactions.

Here’s How We Did it, The Tech Version:

Once we had decided on a new model, implementing the changes was straightforward. We started bottom up, first updating the database and converting the existing data to the new format.  Next was the Golang data layer, and, finally, the front end. ActiveGiver has two areas of the front end that were affected: the BackOffice (administration panel) and the Campaign Dashboard. The BackOffice is where the content development team works to implement causes and onboard politicians. Because of the small size of our team, we opted to use an Angular.js framework called ng-admin to construct the BackOffice rather than build it ourselves. The ng-admin remodel was painless and was mostly telling ng-admin how to interpret the new JSON data. The Campaign Dashboard is the page that politicians or campaign representatives can log on to to see how their causes are doing, find more causes that they support, or change their information. The Campaign Dashboard was written in-house and is HTML/CSS/Javascript on top of Golang. The remodel was also very painless, but, since we were already altering the code, we decided to implement a framework to create bindings between the data layer and front end. Previously, whenever a campaign representative wanted to update their information, the Campaign Dashboard would have to submit a form and reload the whole page to show the changes. The new binding allows the update request to be sent back and update the current page without having to reload. There are many frameworks that can do this – Angular and Backbone to name two of the most popular, however, we decided on Knockout.js.

Knockout.js is somewhat of a weird beast. In order to create the bindings, Knockout uses Observables, functions that “notify subscribers about changes”. Basically, if two people are trying to have a conversation, rather than talking to each other directly they have to write messages and pass them through a third person. The reason behind this design choice is actually related to compatibility, but can lead to extremely complicated situations if Knockout is used too expansively or too haphazardly. Keeping that in mind, we chose Knockout because of its relatively low impact on the rest of the code. Implementing the bindings required nothing other than adding some basic struct-like/class-like definitions to the javascript and connecting them to the HTML. With the new data model in place and a new webpage about to launch, we’re gearing up for the important election cycles this coming year.

– Colter, Development

Leave a comment