diff --git a/lib/api/index.js b/lib/api/index.js index a9e5e25f873..ec279e3119e 100644 --- a/lib/api/index.js +++ b/lib/api/index.js @@ -62,6 +62,7 @@ function create (env, ctx) { app.use('/', wares.sendJSONStatus, require('./adminnotifiesapi')(ctx)); app.all('/food*', require('./food/')(app, wares, ctx)); + app.all('/insulin*', require('./insulin/')(app, wares, ctx)); // Status first app.all('/status*', require('./status')(app, wares, env, ctx)); diff --git a/lib/api/insulin/index.js b/lib/api/insulin/index.js new file mode 100644 index 00000000000..beb39626f83 --- /dev/null +++ b/lib/api/insulin/index.js @@ -0,0 +1,100 @@ +'use strict'; + +var consts = require('../../constants'); + +function configure (app, wares, ctx) { + var express = require('express'), + api = express.Router( ); + + // invoke common middleware + api.use(wares.sendJSONStatus); + // text body types get handled as raw buffer stream + api.use(wares.bodyParser.raw( )); + // json body types get handled as parsed json + api.use(wares.bodyParser.json( )); + // also support url-encoded content-type + api.use(wares.bodyParser.urlencoded({ extended: true })); + + api.use(ctx.authorization.isPermitted('api:insulin:read')); + // List profiles available + api.get('/insulin/', function(req, res) { + ctx.insulin.list(function (err, attribute) { + return res.json(attribute); + }); + }); + + // List bolus insulin profile + api.get('/insulin/bolus', function(req, res) { + ctx.insulin.bolus( function(err, records) { + return res.json(records.length > 0 ? records[0] : null); + }); + }); + + // List basal insulin profile + api.get('/insulin/basal', function(req, res) { + ctx.insulin.bolus( function(err, records) { + return res.json(records.length > 0 ? records[0] : null); + }); + }); + + function config_authed (app, api, wares, ctx) { + + // create new record + api.post('/insulin/', ctx.authorization.isPermitted('api:insulin:create'), async function(req, res) { + var data = req.body; + for (let i = 0, l = data.length; i < l; i++) + { + let result = await ctx.insulin.searchByName(data[i].name); + if (result.length > 0) + { + let err = "insulin profile with this name (" + data[i].name + ") already present - use update instead"; + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Data Error', err); + console.log('Error creating insulin'); + console.log(err); + return; + } + } + ctx.insulin.create(data, function (err, created) { + if (err) { + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); + console.log('Error creating insulin'); + console.log(err); + } else { + res.json(created.ops); + console.log('Insulin created', created); + } + }); + }); + + // update record + api.put('/insulin/', ctx.authorization.isPermitted('api:insulin:update'), function(req, res) { + var data = req.body; + ctx.insulin.save(data, function (err, created) { + if (err) { + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); + console.log('Error saving insulin'); + console.log(err); + } else { + res.json(created); + console.log('Insulin saved', created); + } + + }); + }); + + api.delete('/insulin/:_id', ctx.authorization.isPermitted('api:insulin:delete'), function(req, res) { + ctx.insulin.remove(req.params._id, function ( ) { + res.json({ }); + }); + }); + } + + if (app.enabled('api')) { + config_authed(app, api, wares, ctx); + } + + return api; +} + +module.exports = configure; + diff --git a/lib/api/status.js b/lib/api/status.js index fe736b00c7c..348b95e1017 100644 --- a/lib/api/status.js +++ b/lib/api/status.js @@ -33,6 +33,7 @@ function configure (app, wares, env, ctx) { , serverTime: date.toISOString() , serverTimeEpoch: date.getTime() , apiEnabled: app.enabled('api') + , insulinAvailable: app.enabled('api') , careportalEnabled: app.enabled('api') && env.settings.enable.indexOf('careportal') > -1 , boluscalcEnabled: app.enabled('api') && env.settings.enable.indexOf('boluscalc') > -1 , settings: settings diff --git a/lib/server/bootevent.js b/lib/server/bootevent.js index b377abcce98..5c47fddc6e6 100644 --- a/lib/server/bootevent.js +++ b/lib/server/bootevent.js @@ -232,6 +232,7 @@ function boot (env, language) { ctx.devicestatus = require('./devicestatus')(env.devicestatus_collection, ctx); ctx.profile = require('./profile')(env.profile_collection, ctx); ctx.food = require('./food')(env, ctx); + ctx.insulin = require('./insulin')(env.insulin_collection, ctx); ctx.pebble = require('./pebble')(env, ctx); ctx.properties = require('../api2/properties')(env, ctx); ctx.ddata = require('../data/ddata')(); @@ -268,6 +269,7 @@ function boot (env, language) { ctx.store.ensureIndexes(ctx.treatments( ), ctx.treatments.indexedFields); ctx.store.ensureIndexes(ctx.devicestatus( ), ctx.devicestatus.indexedFields); ctx.store.ensureIndexes(ctx.profile( ), ctx.profile.indexedFields); + ctx.store.ensureIndexes(ctx.insulin( ), ctx.insulin.indexedFields); ctx.store.ensureIndexes(ctx.food( ), ctx.food.indexedFields); ctx.store.ensureIndexes(ctx.activity( ), ctx.activity.indexedFields); diff --git a/lib/server/env.js b/lib/server/env.js index afb53d51332..01c2154ecb7 100644 --- a/lib/server/env.js +++ b/lib/server/env.js @@ -128,6 +128,7 @@ function setStorage () { env.settings_collection = readENV('MONGO_SETTINGS_COLLECTION', 'settings'); env.devicestatus_collection = readENV('MONGO_DEVICESTATUS_COLLECTION', 'devicestatus'); env.food_collection = readENV('MONGO_FOOD_COLLECTION', 'food'); + env.insulin_collection = readENV('MONGO_INSULIN_COLLECTION', 'insulin'); env.activity_collection = readENV('MONGO_ACTIVITY_COLLECTION', 'activity'); var DB = { url: null, collection: null } diff --git a/lib/server/insulin.js b/lib/server/insulin.js new file mode 100644 index 00000000000..31186f7eb64 --- /dev/null +++ b/lib/server/insulin.js @@ -0,0 +1,64 @@ +'use strict'; + +function storage (collection, ctx) { + var ObjectID = require('mongodb').ObjectID; + + function create (obj, fn) { + obj.created_at = (new Date( )).toISOString( ); + api().insert(obj, function (err, doc) { + fn(null, doc); + }); + ctx.bus.emit('data-received'); + } + + function save (obj, fn) { + obj._id = new ObjectID(obj._id); + if (!obj.created_at) { + obj.created_at = (new Date( )).toISOString( ); + } + api().save(obj, function (err) { + //id should be added for new docs + fn(err, obj); + }); + ctx.bus.emit('data-received'); + } + + function list (fn) { + return api( ).find({ }).sort({name: -1}).toArray(fn); + } + + function searchByName (name) { + return api( ).find({"name": name}).sort({name: -1}).toArray(); + } + + function bolus (fn) { + return api().find({"active": "bolus" }).limit(1).toArray(fn); + } + + function basal (fn) { + return api().find({"active": "basal" }).limit(1).toArray(fn); + } + + function remove (_id, fn) { + var objId = new ObjectID(_id); + api( ).remove({ '_id': objId }, fn); + + ctx.bus.emit('data-received'); + } + + function api () { + return ctx.store.collection(collection); + } + + api.list = list; + api.create = create; + api.save = save; + api.remove = remove; + api.bolus = bolus; + api.basal = basal; + api.searchByName = searchByName; + api.indexedFields = ['name']; + return api; +} + +module.exports = storage;