Skip to content
This repository has been archived by the owner on Jan 31, 2018. It is now read-only.

Commit

Permalink
Merge pull request #391 from willkg/1103141-add-experiment_version
Browse files Browse the repository at this point in the history
[bug 1103141] Add experiment_version to HB db and api
  • Loading branch information
willkg committed Nov 21, 2014
2 parents bc2e978 + f5fe5cf commit 30e0d64
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 44 deletions.
93 changes: 52 additions & 41 deletions docs/hb_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,53 @@ These fields are required and have no defaults. If you do not provide
them, then you'll get back an HTTP 400 with a message stating you
missed a required field.

+----------------+-------+--------------------------------------------------------+
|field |type |notes |
+================+=======+========================================================+
|person_id |string |max length: 50; Id representating a person's browser. |
| | |Global across surveys and flows. |
+----------------+-------+--------------------------------------------------------+
|survey_id |string |This is the survey name as it is set up in Input. This |
| | |is the only field that has a foreign key to another |
| | |table in Input and must be set up before running a |
| | |survey. |
| | | |
+----------------+-------+--------------------------------------------------------+
|flow_id |string |max length: 50; Id uniquely identifying a flow attempt |
| | |for this survey. |
| | | |
| | | |
| | | |
+----------------+-------+--------------------------------------------------------+
|question_id |string |max length: 50; Id uniquely identifying a question for |
| | |this survey. This allows us to tweak the question text |
| | |for a survey without launching a new survey. |
| | | |
| | | |
+----------------+-------+--------------------------------------------------------+
|response_version|integer|This is the version of the packet specification. Any |
| | |time the values of the packet or the calculation of the |
| | |values for the packet change, we should increase the |
| | |``response_version``. This allows us to distinguish |
| | |between different packet builds when doing analysis. |
+----------------+-------+--------------------------------------------------------+
|updated_ts |integer|Milliseconds since the epoch for when this packet was |
| | |created. |
| | | |
| | |Every time you update data for a flow attempt, it should|
| | |include a new and more recent ``updated_ts``. |
+----------------+-------+--------------------------------------------------------+
|question_text |string |Max length: None; Default: ``""``; The actual question |
| | |asked. This can be localized. |
+----------------+-------+--------------------------------------------------------+
|variation_id |string |Max length: 50; Default: ``""`` |
+----------------+-------+--------------------------------------------------------+
+------------------+-------+--------------------------------------------------------+
|field |type |notes |
+==================+=======+========================================================+
|response_version |integer|This is the version of the packet specification. Any |
| | |time the values of the packet or the calculation of the |
| | |values for the packet change, we should increase the |
| | |``response_version``. This allows us to distinguish |
| | |between different packet builds when doing analysis. |
+------------------+-------+--------------------------------------------------------+
|experiment_version|string |Max length: 50; The version of the experiment addon. |
| | | |
| | | |
| | | |
| | | |
+------------------+-------+--------------------------------------------------------+
|person_id |string |Max length: 50; Id representating a person's browser. |
| | |Global across surveys and flows. |
+------------------+-------+--------------------------------------------------------+
|survey_id |string |This is the survey name as it is set up in Input. This |
| | |is the only field that has a foreign key to another |
| | |table in Input and must be set up before running a |
| | |survey. |
| | | |
+------------------+-------+--------------------------------------------------------+
|flow_id |string |Max length: 50; Id uniquely identifying a flow attempt |
| | |for this survey. |
| | | |
| | | |
| | | |
+------------------+-------+--------------------------------------------------------+
|question_id |string |Max length: 50; Id uniquely identifying a question for |
| | |this survey. This allows us to tweak the question text |
| | |for a survey without launching a new survey. |
| | | |
| | | |
+------------------+-------+--------------------------------------------------------+
|updated_ts |integer|Milliseconds since the epoch for when this packet was |
| | |created. |
| | | |
| | |Every time you update data for a flow attempt, it should|
| | |include a new and more recent ``updated_ts``. |
+------------------+-------+--------------------------------------------------------+
|question_text |string |Max length: None; Default: ``""``; The actual question |
| | |asked. This can be localized. |
+------------------+-------+--------------------------------------------------------+
|variation_id |string |Max length: 100; Default: ``""`` |
+------------------+-------+--------------------------------------------------------+


Optional fields
Expand Down Expand Up @@ -159,6 +165,7 @@ Example curl::
"person_id": "c1dd81f2-6ece-11e4-8a01-843a4bc832e4",
"survey_id": "lunch",
"flow_id": "20141117_attempt1",
"experiment_version": "1",
"response_version": 1,
"question_id": "howwaslunch",
"question_text": "how was lunch?",
Expand Down Expand Up @@ -200,6 +207,7 @@ Example curl::
"survey_id": "nonexistent",
"flow_id": "20141114_attempt2",
"response_version": 1,
"experiment_version": "1",
"question_id": "howwaslunch",
"updated_ts": 1416011156000,
"is_test": true
Expand Down Expand Up @@ -257,6 +265,7 @@ Anything less than this will kick up "required" type errors.
"person_id": "c1dd81f2-6ece-11e4-8a01-843a4bc832e4",
"survey_id": "lunch",
"flow_id": "20141117_attempt1",
"experiment_version": "1",
"response_version": 1,
"question_id": "howwaslunch",
"question_text": "how was lunch?",
Expand Down Expand Up @@ -284,6 +293,7 @@ Began:
"person_id": "c1dd81f2-6ece-11e4-8a01-843a4bc832e4",
"survey_id": "lunch",
"flow_id": "20141117_attempt5",
"experiment_version": "1",
"response_version": 1,
"question_id": "howwaslunch",
"updated_ts": 1416011156000,
Expand Down Expand Up @@ -319,6 +329,7 @@ Voted, but not engaged, yet::
"person_id": "c1dd81f2-6ece-11e4-8a01-843a4bc832e4",
"survey_id": "lunch",
"flow_id": "20141117_attempt7",
"experiment_version": "1",
"response_version": 1,
"question_id": "howwaslunch",
"updated_ts": 1416011180000,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding field 'Answer.experiment_version'
db.add_column(u'heartbeat_answer', 'experiment_version',
self.gf('django.db.models.fields.CharField')(default='', max_length=50),
keep_default=False)


def backwards(self, orm):
# Deleting field 'Answer.experiment_version'
db.delete_column(u'heartbeat_answer', 'experiment_version')


models = {
u'heartbeat.answer': {
'Meta': {'object_name': 'Answer'},
'addons': ('fjord.base.models.JSONObjectField', [], {'default': '{}', 'blank': 'True'}),
'build_id': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'channel': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'experiment_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'extra': ('fjord.base.models.JSONObjectField', [], {'default': '{}', 'blank': 'True'}),
'flow_began_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'flow_engaged_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'flow_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'flow_offered_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'flow_voted_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_test': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'locale': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'max_score': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'partner_id': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'person_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'platform': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'profile_age': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
'profile_usage': ('fjord.base.models.JSONObjectField', [], {'default': '{}', 'blank': 'True'}),
'question_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'question_text': ('django.db.models.fields.TextField', [], {}),
'response_version': ('django.db.models.fields.IntegerField', [], {}),
'score': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'survey_id': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['heartbeat.Survey']", 'to_field': "'name'", 'db_column': "'survey_id'"}),
'updated_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'variation_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'version': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'})
},
u'heartbeat.survey': {
'Meta': {'object_name': 'Survey'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
}
}

complete_apps = ['heartbeat']
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):

# Changing field 'Answer.variation_id'
db.alter_column(u'heartbeat_answer', 'variation_id', self.gf('django.db.models.fields.CharField')(max_length=100))

def backwards(self, orm):

# Changing field 'Answer.variation_id'
db.alter_column(u'heartbeat_answer', 'variation_id', self.gf('django.db.models.fields.CharField')(max_length=50))

models = {
u'heartbeat.answer': {
'Meta': {'object_name': 'Answer'},
'addons': ('fjord.base.models.JSONObjectField', [], {'default': '{}', 'blank': 'True'}),
'build_id': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'channel': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'experiment_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'extra': ('fjord.base.models.JSONObjectField', [], {'default': '{}', 'blank': 'True'}),
'flow_began_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'flow_engaged_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'flow_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'flow_offered_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'flow_voted_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_test': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'locale': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'max_score': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'partner_id': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'person_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'platform': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'}),
'profile_age': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
'profile_usage': ('fjord.base.models.JSONObjectField', [], {'default': '{}', 'blank': 'True'}),
'question_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'question_text': ('django.db.models.fields.TextField', [], {}),
'response_version': ('django.db.models.fields.IntegerField', [], {}),
'score': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'survey_id': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['heartbeat.Survey']", 'to_field': "'name'", 'db_column': "'survey_id'"}),
'updated_ts': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'variation_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'version': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '50', 'blank': 'True'})
},
u'heartbeat.survey': {
'Meta': {'object_name': 'Survey'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
}
}

complete_apps = ['heartbeat']
5 changes: 4 additions & 1 deletion fjord/heartbeat/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class Answer(ModelBase):
it can **never** be made publicly available.
"""
# The version of the experiment addon.
experiment_version = models.CharField(max_length=50)

# The version of the HTTP POST packet shape. This allows us to
# change how some of the values in the packet are calculated and
# distinguish between different iterations of answers for the same
Expand All @@ -61,7 +64,7 @@ class Answer(ModelBase):
# The id, text and variation of the question being asked.
question_id = models.CharField(max_length=50)
question_text = models.TextField()
variation_id = models.CharField(max_length=50)
variation_id = models.CharField(max_length=100)

# score out of max_score. Use null for no value.
score = models.FloatField(null=True, blank=True)
Expand Down
1 change: 1 addition & 0 deletions fjord/heartbeat/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class AnswerFactory(factory.DjangoModelFactory):
class Meta:
model = Answer

experiment_version = '1'
response_version = 1
updated_ts = int(time.time())
survey = factory.SubFactory(SurveyFactory)
Expand Down

0 comments on commit 30e0d64

Please sign in to comment.