Mental Tracking

Tracking how I feel each day to better understand myself.

Project Categories: code personal-health

I've had this project in the back of my mind for quite some time, so its probably a good thing to finally put something in writing. Basically I want to track mental wellness over time. I'd love to pull in some data from physical wellness as well, like my jawbone/misfit data and sleep data but thats a secondary aspect.

I put up - or at least try my best to - a lot of mental facades, especially in professional and related settings, but sometimes it gets to the point where I end up fooling myself for even hours after its safe to tear them down. BUT I'd love to track the inside view, the behind the door look into how I'm doing each day.

Using just a couple of questions, ranging from multiple choice to scales, and maybe even some short prompts, I bet I could get a pretty good historical view into how I'm doing each day.

I'd love to be able to define these as something like a YAML file:

- prompt: How happy are you today?
  type: scale
  options:
    - :(
    - :|
    - :)

- prompt: Was today a good day?
  type: scale
  options:
    - yes
    - no

- prompt: What was bad today?
  type: multiple_choice
  options:
    - Stress
    - Workload
    - Physical Pains

And so forth. I like the idea of being able to just add or update or remove questions really quickly, until I've narrowed it down to something that I feel really maps out my day.

I'd also love to have this setup as like a three or four per day sort of system, with it sending me a notification with a link to the current questionnaire when its time. Maybe even add a "weight" option that decreases as time passes since the questionnaire was sent out.

UPDATE 2016-02-12 I started work on this project superbowl night (didn't watch; code instead) and have naturally over engineered it, as is my style. I've built out a small Sinatra and Sequel backed app that has primarily HAML based views however the actual answering of questions is a little React component. I've put the source code up on github and am working on finishing things up since its a fairly small project to start off with.

A little bit about how I've modeled this and why I went this route:

I initially was thinking of backing this whole thing with a google spreadsheet since they are easy for super fast, and surprisingly somewhat complex analysis and insight into the data. I quickly abandoned directly interfacing with google however since it seems like every gem out there to do that is awful. So I decided to stick it all into Postgres for the time being since I've already got the infrastructure setup to handle working with it, both on my system as a whole and in ruby.

I tried to think about reusability of the whole system, and making it fairly easy to adapt in the future by making it simple now. As a result I've got 4 major parts: Questions, Questionnaire Templates, Questionnaires and Responses.

A question is just what it sounds like. It's a table that has:

  • prompt - What's being asked, fairly obvious.
  • type - What type of question is this? Free form text reply, multiple choice, single choice?
  • choices - A postgres array for use in multiple choice and single choice questions
  • meta - A JSONB column for possible expansion. Mostly for rapid prototyping that will eventually end up as its own column

Questions are designed to be independent of everything else, so that they can be reused across questionnaires. As a result everything references them and they live off in their own little corner of things.

Questionnaire Templates are designed to be groups of questions that represent a single questionnaire:

  • name
  • description
  • question_ids - A Postgres Array of question IDs, ordered according to presentation order

Questionnaires use a Questionnaire Template, telling it which questions are going to be answered, and acts as a container for a set of responses to those questions.

  • user_id
  • questionnaire_template
  • completed - Boolean field for quick sorting. Set to TRUE when there are an equal amount of responses to questions (not ideal but works).

Responses belong to a question, and happen within a session (Questionnaire, see below):

  • question_id
  • questionnaire_id
  • responses - A Postgres Array of choices

If the question is of type: :text then the responses array has one element, representing that text response. Likewise, if it is a single choice or multiple choice the responses array has all the choices selected from the question. So far this has worked pretty well, and as I said above, I'm almost done with the basic functionality of the system.

Updates coming later