Skip to content

Commit

Permalink
feat: add campaign http router
Browse files Browse the repository at this point in the history
  • Loading branch information
lykmapipo committed Jun 16, 2019
1 parent d2b3d6a commit 236f23d
Show file tree
Hide file tree
Showing 3 changed files with 367 additions and 0 deletions.
318 changes: 318 additions & 0 deletions lib/campaign.http.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
'use strict';

/**
* @apiDefine Campaign Campaign
*
* @apiDescription A representation of communication intended by the
* source(sender) for consumption by some recipient(receiver) or group of
* recipients(receivers).
*
* @author lally elias <lallyelias87@gmail.com>
* @license MIT
* @since 0.1.0
* @version 0.1.0
* @public
*/

/**
* @apiDefine Campaign
* @apiSuccess {String} _id Unique campaign identifier
* @apiSuccess {String} [form] campaign form i.e Alert, Announcement etc
* @apiSuccess {String} title title of the campaign i.e email title etc
* @apiSuccess {Object} sender sender of the campaign messages i.e e-mail
* sender, sms sender etc.
* @apiSuccess {String} [sender.name] sender name
* @apiSuccess {String} [sender.email] sender email address
* @apiSuccess {String} [sender.mobile] sender mobile phone number or sender id
* @apiSuccess {String} subject subject of the campaign i.e email title etc
* @apiSuccess {String} message content of the campaign to be conveyed to
* receiver(s) or recepient(s) as message body.
* @apiSuccess {String[]} [audiences] Target audiences for a campaign
* e.g SMS, EMAIL etc.
* @apiSuccess {String[]} [channels] Allowed channels to be used to send a
* campaign e.g SMS, EMAIL etc.
* @apiSuccess {Object} [criteria] Application specific conditions to query
* for recipients.
* @apiSuccess {Object} [statistics] General campaign summary for sent,
* delivery, failed etc. messages.
* @apiSuccess {Date} [createdAt] Date when campaign was created
* @apiSuccess {Date} [updatedAt] Date when campaign was last updated
*
*/

/**
* @apiDefine Campaigns
* @apiSuccess {Object[]} data List of campaigns
* @apiSuccess {String} [data.form] campaign form i.e Alert, Announcement etc
* @apiSuccess {String} data.title title of the campaign i.e email title etc
* @apiSuccess {Object} data.sender sender of the campaign messages i.e e-mail
* sender, sms sender etc.
* @apiSuccess {String} [data.sender.name] sender name
* @apiSuccess {String} [data.sender.email] sender email address
* @apiSuccess {String} [data.sender.mobile] sender mobile phone number or
* sender id
* @apiSuccess {String} data.subject subject of the campaign i.e email title etc
* @apiSuccess {String} data.message content of the campaign to be conveyed to
* receiver(s) or recepient(s) as message body.
* @apiSuccess {String[]} [data.audiences] Target audiences for a campaign
* e.g SMS, EMAIL etc.
* @apiSuccess {String[]} [data.channels] Allowed channels to be used to send a
* campaign e.g SMS, EMAIL etc.
* @apiSuccess {Object} [data.criteria] Application specific conditions to query
* for recipients.
* @apiSuccess {Object} [data.statistics] General campaign summary for sent,
* delivery, failed etc. messages.
* @apiSuccess {Date} [data.createdAt] Date when campaign was created
* @apiSuccess {Date} [data.updatedAt] Date when campaign was last updated
* @apiSuccess {Number} total Total number of campaign
* @apiSuccess {Number} size Number of campaigns returned
* @apiSuccess {Number} limit Query limit used
* @apiSuccess {Number} skip Query skip/offset used
* @apiSuccess {Number} page Page number
* @apiSuccess {Number} pages Total number of pages
* @apiSuccess {Date} lastModified Date and time at which latest campaign
* was last modified
*
*/

/**
* @apiDefine CampaignSuccessResponse
* @apiSuccessExample {json} Success-Response:
* {
* _id: "5d05e46ea97493202b17d3ca",
* form: "Alert",
* sender:{ "email": "federico24@gmail.com" },
* title: "Minima aut facilis atque sed et.",
* subject: "Minima aut facilis atque sed et.",
* message: "Omnis et natus delectus eveniet ut rerum minus.",
* }
*
*/

/**
* @apiDefine CampaignsSuccessResponse
* @apiSuccessExample {json} Success-Response:
* {
* "data": [{
* _id: "5d05e46ea97493202b17d3ca",
* form: "Alert",
* sender:{ "email": "federico24@gmail.com" },
* title: "Minima aut facilis atque sed et.",
* subject: "Minima aut facilis atque sed et.",
* message: "Omnis et natus delectus eveniet ut rerum minus.",
* }],
* "total": 20,
* "size": 10,
* "limit": 10,
* "skip": 0,
* "page": 1,
* "pages": 2,
* "lastModified": "2018-07-29T10:11:38.111Z"
* }
*
*/

/* dependencies */
const { getString } = require('@lykmapipo/env');
const {
getFor,
schemaFor,
downloadFor,
getByIdFor,
postFor,
patchFor,
putFor,
deleteFor,
Router,
} = require('@lykmapipo/express-rest-actions');
const Campaign = require('./campaign.model');

/* constants */
const API_VERSION = getString('API_VERSION', '1.0.0');
const PATH_SINGLE = '/campaigns/:id';
const PATH_LIST = '/campaigns';
const PATH_EXPORT = '/campaigns/export';
const PATH_SCHEMA = '/campaigns/schema/';

/* declarations */
const router = new Router({
version: API_VERSION,
});

/**
* @api {get} /campaigns List Campaigns
* @apiVersion 1.0.0
* @apiName GetCampaigns
* @apiGroup Campaign
* @apiDescription Returns a list of campaigns
* @apiUse RequestHeaders
* @apiUse Campaigns
*
* @apiUse RequestHeadersExample
* @apiUse CampaignsSuccessResponse
* @apiUse JWTError
* @apiUse JWTErrorExample
* @apiUse AuthorizationHeaderError
* @apiUse AuthorizationHeaderErrorExample
*/
router.get(
PATH_LIST,
getFor({
get: (options, done) => Campaign.get(options, done),
})
);

/**
* @api {get} /campaigns/schema Get Campaign Schema
* @apiVersion 1.0.0
* @apiName GetCampaignSchema
* @apiGroup Campaign
* @apiDescription Returns campaign json schema definition
* @apiUse RequestHeaders
*/
router.get(
PATH_SCHEMA,
schemaFor({
getSchema: (query, done) => {
const jsonSchema = Campaign.jsonSchema();
return done(null, jsonSchema);
},
})
);

/**
* @api {get} /campaigns/export Export Campaigns
* @apiVersion 1.0.0
* @apiName ExportCampaigns
* @apiGroup Campaign
* @apiDescription Export campaigns as csv
* @apiUse RequestHeaders
*/
router.get(
PATH_EXPORT,
downloadFor({
download: (options, done) => {
const fileName = `campaign_exports_${Date.now()}.csv`;
const readStream = Campaign.exportCsv(options);
return done(null, { fileName, readStream });
},
})
);

/**
* @api {post} /campaigns Create New Campaign
* @apiVersion 1.0.0
* @apiName PostCampaign
* @apiGroup Campaign
* @apiDescription Create new campaign
* @apiUse RequestHeaders
* @apiUse Campaign
*
* @apiUse RequestHeadersExample
* @apiUse CampaignSuccessResponse
* @apiUse JWTError
* @apiUse JWTErrorExample
* @apiUse AuthorizationHeaderError
* @apiUse AuthorizationHeaderErrorExample
*/
router.post(
PATH_LIST,
postFor({
post: (body, done) => Campaign.post(body, done), // TODO create & send
})
);

/**
* @api {get} /campaigns/:id Get Existing Campaign
* @apiVersion 1.0.0
* @apiName GetCampaign
* @apiGroup Campaign
* @apiDescription Get existing campaign
* @apiUse RequestHeaders
* @apiUse Campaign
*
* @apiUse RequestHeadersExample
* @apiUse CampaignSuccessResponse
* @apiUse JWTErrorExample
* @apiUse AuthorizationHeaderError
* @apiUse AuthorizationHeaderErrorExample
*/
router.get(
PATH_SINGLE,
getByIdFor({
getById: (options, done) => Campaign.getById(options, done),
})
);

/**
* @api {patch} /campaigns/:id Patch Existing Campaign
* @apiVersion 1.0.0
* @apiName PatchCampaign
* @apiGroup Campaign
* @apiDescription Patch existing campaign
* @apiUse RequestHeaders
* @apiUse Campaign
*
* @apiUse RequestHeadersExample
* @apiUse CampaignSuccessResponse
* @apiUse JWTError
* @apiUse JWTErrorExample
* @apiUse AuthorizationHeaderError
* @apiUse AuthorizationHeaderErrorExample
*/
router.patch(
PATH_SINGLE,
patchFor({
patch: (options, done) => Campaign.patch(options, done), // TODO resend
})
);

/**
* @api {put} /campaigns/:id Put Existing Campaign
* @apiVersion 1.0.0
* @apiName PutCampaign
* @apiGroup Campaign
* @apiDescription Put existing campaign
* @apiUse RequestHeaders
* @apiUse Campaign
*
* @apiUse RequestHeadersExample
* @apiUse CampaignSuccessResponse
* @apiUse JWTError
* @apiUse JWTErrorExample
* @apiUse AuthorizationHeaderError
* @apiUse AuthorizationHeaderErrorExample
*/
router.put(
PATH_SINGLE,
putFor({
put: (options, done) => Campaign.put(options, done), // TODO resend
})
);

/**
* @api {delete} /campaigns/:id Delete Existing Campaign
* @apiVersion 1.0.0
* @apiName DeleteCampaign
* @apiGroup Campaign
* @apiDescription Delete existing campaign
* @apiUse RequestHeaders
* @apiUse Campaign
*
* @apiUse RequestHeadersExample
* @apiUse CampaignSuccessResponse
* @apiUse JWTError
* @apiUse JWTErrorExample
* @apiUse AuthorizationHeaderError
* @apiUse AuthorizationHeaderErrorExample
*/
router.delete(
PATH_SINGLE,
deleteFor({
del: (options, done) => Campaign.del(options, done),
soft: true,
})
);

/* expose campaign router */
module.exports = exports = router;
47 changes: 47 additions & 0 deletions lib/campaign.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/


const _ = require('lodash');
const { getString } = require('@lykmapipo/env');
const {
model,
Expand Down Expand Up @@ -240,6 +241,52 @@ const CampaignSchema = new Schema({
}, SCHEMA_OPTIONS);


/*
*------------------------------------------------------------------------------
* Hooks
*------------------------------------------------------------------------------
*/


/**
* @name onPreValidate
* @description campaign schema pre validate hook
* @since 0.1.0
* @version 0.1.0
* @private
*/
CampaignSchema.pre('validate', function onPreValidate(next) {
this.preValidate(next);
});


/*
*------------------------------------------------------------------------------
* Instances
*------------------------------------------------------------------------------
*/


/**
* @name preValidate
* @function preValidate
* @description run logics before campaign validation
* @param {Function} done a callback to invoke on success or failure
* @return {Campaign|Error} an instance of campaign or error
* @since 0.1.0
* @version 0.1.0
* @private
*/
CampaignSchema.methods.preValidate = function preValidate(next) {

//ensure `title`
this.title = _.trim(this.title) || this.form;

next(null, this);

};


/*
*------------------------------------------------------------------------------
* Statics
Expand Down
2 changes: 2 additions & 0 deletions lib/message.http.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
* title etc
* @apiSuccess {String} [data.body] ontent of the message to be conveyed to
* receiver(s) e.g Hello
* @apiSuccess {Date} [data.createdAt] Date when message was created
* @apiSuccess {Date} [data.updatedAt] Date when message was last updated
* @apiSuccess {Number} total Total number of message
* @apiSuccess {Number} size Number of messages returned
* @apiSuccess {Number} limit Query limit used
Expand Down

0 comments on commit 236f23d

Please sign in to comment.