Ignore:
Timestamp:
03/05/14 22:44:48 (11 years ago)
Author:
hendrikvanantwerpen
Message:

Completed migration to API, without CouchDB proxy.

Move to API is now completed. The full API is password protected, a very
limited API is exposed for respondents, which works with secrets that
are passed in URLs.

Serverside the HTTPResult class was introduced, which is similar to
Promises, but specifically for HTTP. It carries a status code and
response and makes it easier to extract parts of async handling in
separate functions.

Fixed a bug in our schema (it seems optional attributes don't exist but
a required list does). Verification of our schema by grunt-tv4 didn't
work yet. Our schema is organized the wrong way (this is fixable),
but the json-schema schema has problems with simple types and $refs.

Location:
Dev/trunk/src/server/config
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/server/config/check-couchdb.js

    r479 r487  
    77var schema = require('./couchdb-schema');
    88
    9 module.exports = function(couchDbURL) {
    10     var server = new CouchDB(couchDbURL);
     9module.exports = function(couchServerURL,dbName) {
     10    var server = new CouchDB(couchServerURL,dbName);
    1111    var designRe = /^_design\//;
    1212    return server.get('/_all_docs')
  • Dev/trunk/src/server/config/config-couchdb.js

    r479 r487  
    55  ;
    66
    7 var designDocs = require('./couchdb-design-docs');
     7module.exports = function(couchServerURL, dbName, designDocs) {
     8    var server = new CouchDB(couchServerURL);
    89
    9 module.exports = function(couchServerURL) {
    10     var server = new CouchDB(couchServerURL);
     10    if ( !designDocs ) { throw new Error("Forgot to pass design docs to checkCouch."); }
    1111
    1212    console.log("Configuring CouchDB for QED");
     
    1414    return server.get('')
    1515    .then(function(info){
    16         if (info.version !== "1.2.0" ) {
     16        if (info.version !== "1.4.0" ) {
    1717            console.log("Found "+info.version+", only tested with CouchDB 1.2.0");
    1818        } else {
    19             console.log("CouchDB 1.2.0 found");
     19            console.log("CouchDB 1.4.0 found");
    2020        }
    2121    }).then(function(res){
  • Dev/trunk/src/server/config/couchdb-design-docs.js

    r480 r487  
    1111
    1212    "qed/schemaInfo": {
    13         version: "1"
     13        version: "2"
    1414    },
    1515
     
    3131        language: "javascript",
    3232        validate_doc_update: function(newDoc, oldDoc, userCtx, secObj) {
    33             if ( oldDoc && oldDoc.publicationDate ) { throw({forbidden:'Published documents cannot be modified.'}); }
     33            if ( oldDoc && oldDoc.publicationDate ) {
     34                throw({forbidden:'Published documents cannot be modified.'});
     35            }
    3436        },
    3537        views: {
     
    5961                    if ( doc.categories && doc.categories.length > 0 ) {
    6062                        for ( var i = 0; i < doc.categories.length; i++ ) {
    61                             emit([doc.categories[i],doc.topic||null],1);
     63                            emit([doc.categories[i],doc.topic||"(default)"],1);
    6264                        }
    6365                    } else {
    64                         emit([null,null],1);
     66                        emit(["(default)","(default)"],1);
    6567                    }
    6668                },
     
    7274                    if ( doc.categories && doc.categories.length > 0 ) {
    7375                        for ( var i = 0; i < doc.categories.length; i++ ) {
    74                             emit([doc.categories[i],doc.topic||null],1);
     76                            emit([doc.categories[i],doc.topic||"(default)"],1);
    7577                        }
    7678                    } else {
    77                         emit([null,null],1);
     79                        emit(["(default)","(default)"],1);
    7880                    }
    7981                },
     
    8385                map: function(doc){
    8486                    if( doc.type !== 'Question' ){ return; }
    85                     emit(doc.topic);
     87                    emit(doc.topic||"(default)",1);
    8688                },
    87                 reduce: function(key, values, rereduce) { return null; }
     89                reduce: function(key, values, rereduce) { return sum(values); }
    8890            },
    8991            published_topics: {
    9092                map: function(doc){
    9193                    if ( doc.type !== 'Question' || !doc.publicationDate ) { return; }
    92                     emit(doc.topic);
     94                    emit(doc.topic||"(default)",1);
    9395                },
    94                 reduce: function(key, values, rereduce) { return null; }
     96                reduce: function(key, values, rereduce) { return sum(values); }
     97            },
     98            by_code: {
     99                map: function(doc){
     100                    if ( doc.type !== 'Question' ) { return; }
     101                    emit(doc.code,doc);
     102                }
    95103            }
    96104        }
  • Dev/trunk/src/server/config/couchdb-schema.json

    r481 r487  
    11{
     2  "$schema": "http://json-schema.org/draft-04/schema#",
    23  "title": "QED Object Schema",
    3   "version": "1",
     4  "version": "2",
    45  "type": "object",
    56  "oneOf": [
    6     { "$ref": "#/schemaInfo" },
    7     { "$ref": "#/docTypes/any" }
     7    { "$ref": "#/definitions/schemaInfo" },
     8    { "$ref": "#/definitions/docs/any" }
    89  ],
    9   "schemaInfo": {
    10     "type": "object",
    11     "properties": {
    12         "_id": { "type": "string", "pattern": "schemaInfo" },
    13         "_rev": { "type": "string", "optional": true },
    14         "version": { "type": "string" }
    15     },
    16     "additionalProperties": false
    17   },
    18   "docTypes": {
    19     "any": {
     10  "definitions": {
     11    "schemaInfo": {
    2012      "type": "object",
    21       "oneOf": [
    22         { "$ref": "#/docTypes/Question" },
    23         { "$ref": "#/docTypes/Survey" },
    24         { "$ref": "#/docTypes/SurveyRun" },
    25         { "$ref": "#/docTypes/Response" }
    26       ]
    27     },
    28     "Question": {
    2913      "properties": {
    30         "type": { "type": "string", "pattern": "Question" },
    31         "_id": { "type": "string", "optional": true },
    32         "_rev": { "type": "string", "optional": true },
    33         "categories": { "type": "array", "items": { "type": "string" } },
    34         "code": { "type": "string" },
    35         "content": { "type": "array", "items": { "$ref": "#/contentTypes/any" } },
    36         "description": { "type": "string", "optional": true },
    37         "publicationDate": { "type": "string", "pattern": "", "optional": true },
    38         "title": { "type": "string" },
    39         "topic": { "type": "string", "optional": true }
     14          "_id": { "type": "string", "pattern": "schemaInfo" },
     15          "_rev": { "type": "string" },
     16          "version": { "type": "string" }
    4017      },
     18      "required": ["_id","version"],
    4119      "additionalProperties": false
    4220    },
    43     "Survey": {
    44       "type": "object",
    45       "properties": {
    46         "type": { "type": "string", "pattern": "Survey" },
    47         "_id": { "type": "string", "optional": true },
    48         "_rev": { "type": "string", "optional": true },
    49         "publicationDate": { "type": "string", "pattern": "", "optional": true },
    50         "questions": { "type": "array", "items": { "$ref": "#/docTypes/Question" } },
    51         "title": { "type": "string" }
     21    "docs": {
     22      "any": {
     23        "type": "object",
     24        "oneOf":[
     25          { "$ref": "#/definitions/docs/Question" },
     26          { "$ref": "#/definitions/docs/Survey" },
     27          { "$ref": "#/definitions/docs/SurveyRun" },
     28          { "$ref": "#/definitions/docs/Response" }
     29        ]
    5230      },
    53       "additionalProperties": false
    54     },
    55     "SurveyRun": {
    56       "type": "object",
    57       "properties": {
    58         "type": { "type": "string", "pattern": "SurveyRun" },
    59         "_id": { "type": "string", "optional": true },
    60         "_rev": { "type": "string", "optional": true },
    61         "description": { "type": "string" },
    62         "endDate": { "type": "string", "pattern": "" },
    63         "mode": { "type": "string", "enum": [ "open", "closed" ] },
    64         "startDate": { "type": "string", "pattern": "" },
    65         "survey": { "$ref": "#/docTypes/Survey" },
    66         "title": { "type": "string" }
    67       },
    68       "additionalProperties": false
    69     },
    70     "Response": {
    71       "type": "object",
    72       "properties": {
    73         "type": { "type": "string", "pattern": "Response" },
    74         "_id": { "type": "string", "optional": true },
    75         "_rev": { "type": "string", "optional": true },
    76         "answers": { "type": "object" },
    77         "publicationDate": { "type": "string", "pattern": "", "optional": true },
    78         "surveyRunId": { "type": "string" }
    79       },
    80       "additionalProperties": false
    81     }
    82   },
    83   "contentTypes": {
    84     "any": {
    85       "type": "object",
    86       "oneOf": [
    87         { "$ref": "#/contentTypes/Text" },
    88         { "$ref": "#/contentTypes/StringInput" },
    89         { "$ref": "#/contentTypes/ScaleInput" }
    90       ]
    91     },
    92     "Text": {
     31      "Question": {
    9332        "type": "object",
    9433        "properties": {
    95             "type": { "type": "string", "pattern": "Text" },
    96             "text": { "type": "string" }
     34          "type": { "type": "string", "pattern": "Question" },
     35          "_id": { "type": "string" },
     36          "_rev": { "type": "string" },
     37          "categories": { "type": "array", "items": { "type": "string" } },
     38          "code": { "type": "string" },
     39          "content": { "type": "array", "items": { "$ref": "#/definitions/content/any" } },
     40          "description": { "type": "string" },
     41          "publicationDate": { "type": "string", "format": "datetime" },
     42          "title": { "type": "string" },
     43          "topic": { "type": "string" }
    9744        },
     45        "required": ["type","categories","code","content","title"],
    9846        "additionalProperties": false
    99     },
    100     "StringInput": {
     47      },
     48      "Survey": {
    10149        "type": "object",
    10250        "properties": {
    103             "type": { "type": "string", "pattern": "StringInput" },
    104             "text": { "type": "string" }
     51          "type": { "type": "string", "pattern": "Survey" },
     52          "_id": { "type": "string" },
     53          "_rev": { "type": "string" },
     54          "publicationDate": { "type": "string", "format": "datetime" },
     55          "questions": { "type": "array", "items": { "$ref": "#/definitions/docs/Question" } },
     56          "title": { "type": "string" }
    10557        },
     58        "required": ["type","questions","title"],
    10659        "additionalProperties": false
    107     },
    108     "ScaleInput": {
     60      },
     61      "SurveyRun": {
    10962        "type": "object",
    11063        "properties": {
    111             "type": { "type": "string", "pattern": "ScaleInput" },
    112             "minLabel": { "type": "string", "optional": true },
    113             "min": { "type": "integer" },
    114             "max": { "type": "integer" },
    115             "maxLabel": { "type": "string", "optional": true },
    116             "naLabel": { "type": "string", "optional": true },
    117             "items": { "type": "array", "items": {
    118                 "type": "object",
    119                 "properties": {
    120                     "text": { "type": "string" },
    121                     "minLabel": { "type": "string", "optional": true },
    122                     "maxLabel": { "type": "string", "optional": true }
    123                 },
    124                 "additionalProperties": false
    125             } }
     64          "type": { "type": "string", "pattern": "SurveyRun" },
     65          "_id": { "type": "string" },
     66          "_rev": { "type": "string" },
     67          "description": { "type": "string" },
     68          "endDate": { "type": "string", "format": "datetime" },
     69          "mode": { "type": "string", "enum": [ "open", "closed" ] },
     70          "secret": { "type": "string", "minLength": 8 },
     71          "startDate": { "type": "string", "format": "datetime" },
     72          "survey": { "$ref": "#/definitions/docs/Survey" },
     73          "title": { "type": "string" }
    12674        },
     75        "required": ["type","description","mode","secret","survey","title"],
    12776        "additionalProperties": false
     77      },
     78      "Response": {
     79        "type": "object",
     80        "properties": {
     81          "type": { "type": "string", "pattern": "Response" },
     82          "_id": { "type": "string" },
     83          "_rev": { "type": "string" },
     84          "answers": { "type": "object" },
     85          "publicationDate": { "type": "string", "format": "datetime" },
     86          "secret": { "type": "string", "minLength": 8 },
     87          "surveyRunId": { "type": "string" }
     88        },
     89        "required": ["type","answers","secret","surveyRunId"],
     90        "additionalProperties": false
     91      }
     92    },
     93    "content":{
     94      "any": {
     95        "type": "object",
     96        "oneOf": [
     97          { "$ref": "#/definitions/content/Text" },
     98          { "$ref": "#/definitions/content/StringInput" },
     99          { "$ref": "#/definitions/content/ScaleInput" }
     100        ]
     101      },
     102      "Text": {
     103        "type": "object",
     104        "properties": {
     105          "type": { "type": "string", "pattern": "Text" },
     106          "text": { "type": "string" }
     107        },
     108        "required": ["type","text"],
     109        "additionalProperties": false
     110      },
     111      "StringInput": {
     112        "type": "object",
     113        "properties": {
     114          "type": { "type": "string", "pattern": "StringInput" },
     115          "text": { "type": "string" }
     116        },
     117        "required":["type","text"],
     118        "additionalProperties": false
     119      },
     120      "ScaleInput": {
     121        "type": "object",
     122        "properties": {
     123          "type": { "type": "string", "pattern": "ScaleInput" },
     124          "minLabel": { "type": "string" },
     125          "min": { "type": "integer" },
     126          "max": { "type": "integer" },
     127          "maxLabel": { "type": "string" },
     128          "naLabel": { "type": "string" },
     129          "items": { "type": "array", "items": {
     130            "type": "object",
     131            "properties": {
     132              "text": { "type": "string" },
     133              "minLabel": { "type": "string" },
     134              "maxLabel": { "type": "string" }
     135            },
     136            "required":["text"],
     137            "additionalProperties": false
     138          } }
     139        },
     140        "required":["type","min","max","items"],
     141        "additionalProperties": false
     142      }
    128143    }
    129144  }
Note: See TracChangeset for help on using the changeset viewer.