Skip to content

GlobalDataBarometer/barometer-survey-tool

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

373 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Barometer Survey Tool

The Barometer Survey Tool is a custom application developed to run the Global Data Barometer survey, but possible to adapt for other surveys. It provides for:

  • User authentication - with surveys assigned to specific researchers and reviewers;
  • In-line documentation, auto-saving responses, upload of supporting evidence;
  • A survey workflow: including research, spot-check quality assurance, peer-review and updates to surveys;
  • Custom question types, defined through a simple spreadsheet template;
  • Notes feature to allow feedback on each individual survey element.

This application is an update of the Open Data Barometer survey tool to remove most of dependencies on Google infrastructure from the tool.

Survey workflow

The survey tool implements a workflow with three main roles:

  • Coordinator
  • Primary researcher
  • Reviewer

Each survey can be taken through a workflow covering:

  • Initial research
  • Spot check by coordinator
  • Peer review - reviewers can comment but not update information
  • Secondary research
  • Spot check by coordinator
  • Final validation

Surveys incorporates a range of question types, and conditional logic for the display of supporting questions.

Architecture

The tool consists of a backend Django application that handles user authentication, and provides an API layer between the frontend app and Postgres database to: fetch survey definitions, save survey responses, and store and fetch supporting files.

The backend database makes extensive use of Postgres JSON fields to allow storage of flexible data structures. There is also a database log trigger set-up which will keep a full transaction history of database edits.

A frontend application written in Angular 1.3.20 uses survey definitions from the API to present a survey to authenticated users, who, depending on their role, may complete or comment on each question.

A control application is available written in Google Apps Script to create and manage surveys through a workflow of stages, and to send notification e-mails to users.

Frontend application

The frontend application allows users to create or log-in to an account on the system. Each account has a primary e-mail address attached to it which is used to identify surveys that the user has access to as a coordinator, researcher or reviewer.

The user can then access surveys with the following URL path: /{survey_id}/{question_data_name (optional)}

For example, if a user has been assigned survey 10 and question definitions exist for a default survey, for 'long_survey' and 'short_survey', they can access:

  • /10/long_survey
  • /10/short_survey and
  • /10/

All will read the response data and notes stored for survey 10, but each will present a different set of questions. This can be used to provide respondents with slightly different surveys at different stages of a research if required.

Question definition and layouts

Each question in the survey has an ID, Question and Type and a number of supporting fields used to affect the display of guidance, supporting questions, styling and other features (see question definition documentation below).

The files in /htdocs/tpl/ define how questions are displayed to the user, and allow for a flexible creation of new question types or changes to the way questions are laid out and structured.


Note: The current set of templates in this repository are configured specifically for the Global Data Barometer in the expectation that every question is structured as:

  • A parent question of type 'Status' with SubQuestionFirst = 'Yes' and with WantJustification, WantExamples and HasPrivateNotes set at this level
  • One or more child questions without justification, examples or private notes

Control application

The Control Application is a Google Spreadsheet that will:

  • Create new surveys and update their assignees and status
  • Track completion of each survey

It is written in Google Apps Script. A template copy is available here (make a copy and use Tools -> Script Editor to see the scripts).

Setting up triggers

The control sheet needs two triggers configured to allow it to work. Triggers should be set up as a single user. This user will be the one whose account is used to send out notification mails etc.

  • Go to Tools > Script Editor
  • Choose Resources > Current Triggers
  • Add two triggers - one for ‘onUpdate’ driven ‘From Spreadsheet’ by ‘On edit’ events, and the other for ‘periodicUpdate’ as a ‘Time-driven’ event on an hourly timer.

Setting up Completion Reporting

On updates, the control scripts check current survey completion, and put this into c_X columns, where X is the ID of a section in the survey.

As a control sheet may be used to assign various different surveys with different structures, an administrator should manually create columns left of the 'Completion Map' column to be poplated. These will contain the number of 'Status' questions with a status of 'Complete' or 'Reviewed'.

Backend application

Setting up

See .env.template for details of the different API keys and services needed to deploy a new copy of the appliation.

Logging in

To create an admin user go to the console and run:

./manage.py createsuperuser

Tip: When deployed on Digital Ocean Apps, a web interface to the console is available from the Digital Ocean Cloud.

You can then log-in to the administration interface at tool-address.org/admin/

Django management console

The build in Django Administration tool is mainly used to administer users. All other survey admin should take place using the API.

At /admin/auth/user/ you can see the user accounts created in the tool, and if required, update user passwords.

API

Once authenticated as a 'staff' user, you can access the full API at /api/

This uses the Django REST Framework to expose three endpoints:

  • /api/survey/ - containing a record for each survey with control information (e.g. who is assigned to respond; survey status), question responses, review notes and associated files/supporting evidence.
  • /api/survey-data-types/ - defines the templates used for recording control, responses, notes and file data. This is populated by fixtures, and would only need to change if there were modifications to the front-end application.
  • /api/question-data/ - contains the survey definitions that determine the sections and questions contained for each survey. There is a default survey, and a collection of named surveys available at /api/question-data/list_names/

An authenticated user can GET, PUT or POST to most API endpoints in order to create or update surveys, or to define and update question data.

Note: the API was developed as a rapid drop-in replacement for deprecated Google APIs, and so has some quirks.

Creating and updating question data

Question data consists of three parts:

  • Config - providing general configuration variables for a set of questions. Exposed in config. in angular.
  • Sections - setting up the sections used in the survey.
  • Questions - setting up each individual question.

The easiest way to update question data is to create a Google Spreadsheet with tabs for 'Config', 'Sections' and 'Questions' following this template (see full documentation of fields below) and to set the spreadsheet to be accessible to anyone on the web. Then make a GET request with the spreadsheet key to:

/api/question-data/upload_spreadsheet/?name={SURVEY_NAME}&spreadsheet={SPREADSHEET_KEY}

The tool will then read and refresh the survey definitions from this file and save as {SURVEY_NAME}.

Creating and updating surveys

A survey is created by an authenticated user (HTTP Basic Auth) making a PUT request to /api/survey/ with the following JSON payload:

{
  "control": {
    "Coordinator Email": "coordinator@example.com",
    "Coordinator Name": "Coordinator name",
    "Country": "Survey title",
    "Researcher": "lowercase MD5 hash of researcher e-mail address",
    "Reviewer": "lowercase MD5 hash of reviewer e-mail address",
    "Survey": "name of question_data to use",
    "Status":" One of recruitment, assigned, spotcheck, clarification, review, validation or complete",
    "Status Due":"DD-MM-YYYY"
  }
}

The API will return a survey control record with an assigned id.

To update the details of an existing survey, this can be PUT against /api/survey/{id}

Depending on the survey status, this will then let a user authenticated with the e-mail address hashed in 'researcher' or 'reviewer' to access the survey and provide responses or make review comments.

Survey data

The data for each survey is available at /api/survey/{id}/data/. This can be used to fetch survey responses, although an alternative set of SQL queries for direct access to the database is also provided {TODO}.

Question data definitions

The following section describes the format for a question data definition spreadsheet to use with the upload_spreadsheet feature. Column names are converted to lower-case, no space versions in the API.

Config variables

All config values are passed to the the config. variable in Angular for use in front-end templating.

Variable Value Notes
title The survey title
logo URL to an image to use as survey icon/branding
hide_question_id FALSE Should the ID of questions be displayed in the survey tool?
hide_notes FALSE Choose whether or not to enable to notes feature
justification_note Justification and sources What text should be displayed as a prompt for the justification and sources box?

The spreadsheet template for config follows the table format above exactly.

Sections

The spreadsheet template for sections includes the columns listed below in classic table format.

Column How it is used
Section ID A short alphanumeric identifier. Displayed in header bar
Section An internal label for the section
Title The title to display to users
Description A section description displayed to users. Can contain Markdown

Questions

Column How it is used
Section ID Matches the ID of the section this question is included in
Question ID A unique identifier for the question
Question Type Matching a type for which a template exists in tpl/question.html - currently Note, Option, Description, Scale, Status, Sum, ElementGroup, Element and Radio
Parent ID If provided, this question is grouped under the parent ID. Tree structures can be created this way
SubQuestionsFirst Should child questions be displayed before the substantive part of this question (and before justification/sources for this question)
CSSClass An optional custom CSS class to attach to the question container
Guidance10 Scale questions ask for a response in the range 0 - 10, and can provide guidance for steps of the scale. If using a scale question this will provide guidance on what should count as 10 out of 10
Guidance5 ditto for 5 out of 10
Guidance0 ditto for 0 out of 10
WantConfidence Answer 'Yes' if the user should provide a rating of how confident they are in their reply
WantJustification Answer 'Yes' if the user should provide a free text justification for their response
JustificationNote An optional prompt text to overwrite the default prompt for justification and sources
HasPrivateNotes Answer 'Yes' if the user should provide private notes for the reviewer / coordinator
WantExamples Answer 'Yes' if the user should be able to attach URLs or Files to this question
Multiplier A value between 0 and n to multiply the option response by when using this question as the child of a 'Sum' question. For example, if Multiplier = 0.5, then answering Option 3 adds 1.5 to the parent Sum value
OptionGuidance An optional free text string to display in-line guidance on options presented to the user
Option{0-9} Options presented to the user in Scale, Option, Radio and Element questions
Supporting{0-5} Freetext supporting questions to display. Responses are collected as unvalidated free text. Questions can be made conditional on option responses by prefixing with "{OptionN},{OptionN};Supporting question text". For example, to only display a question if the user responds with Option2 or Option3, Supporting0 would be "2,3;If option 2 or 3, then explain why?"
HelpLink The URL of further question guidance, to be openned in-line

Credits

Original concept and prototype developed in 2013 by Tim Davies for the World Wide Web Foundation. Front-end application developed by Oomph Inc in 2014 with some of the funding for this work originating in the open data common assessmnet methods component of IDRC grant 107075. Subsequent developed undertaken by Carlos Iglesias of the World Wide Web Foundation. Updates to front-end by Ali Blackwell. Re-write of backend system by David Raznick of Open Data Services Co-operative. Further updates and Documentation by Tim Davies.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 57.8%
  • Python 19.7%
  • HTML 13.5%
  • CSS 9.0%