diff --git a/package.json b/package.json index e1e402fa..3aed8c75 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "express": "4.17.1", "express-request-id": "1.4.1", "helmet": "3.22.0", + "json2csv": "^5.0.0", "jsonwebtoken": "8.5.1", "lodash": "^4.17.15", "mocha": "7.1.1", diff --git a/src/routes/csv.js b/src/routes/csv.js new file mode 100644 index 00000000..afa249e3 --- /dev/null +++ b/src/routes/csv.js @@ -0,0 +1,37 @@ +import { Router } from 'express'; +import validator from 'validator'; +import utils from '../utils'; +import { parseAsync } from "json2csv"; + +const router = new Router(); +router.use(utils.authMiddleware) + +// Gets a data dump from the passed in model (if it exists). +router.get('/:model_type', async (req, res) => { + let code; + let message; + const modelType = req.params.model_type; + try { + if(req.context.models.hasOwnProperty(modelType)){ + //todo add filtering + const results = await req.context.models[modelType].findAll({raw:true}); + + const processedResults = await utils.processResults(results, modelType); + + if(results.length !== 0){ + message = await parseAsync(JSON.parse(JSON.stringify(processedResults)), Object.keys(results[0]), {}); + } + code = 200; + } else { + message = "model type is invalid" + code = 422; + } + } catch (e) { + console.error(e); + code = 500; + } + + return utils.response(res, code, message); +}); + +export default router; \ No newline at end of file diff --git a/src/routes/index.js b/src/routes/index.js index fbeb9a15..dca1fc10 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -2,10 +2,12 @@ import user from './user'; // import userRole from './user-role'; import contact from './contact'; import entity from './entity'; +import csv from './csv'; // Exports object of routes we import above. Add to this if you're adding new routes. export default { user, // userRole, contact, - entity + entity, + csv }; diff --git a/src/utils/index.js b/src/utils/index.js index a839dc2a..2b7f2c33 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -109,10 +109,36 @@ const validateEmails = async emails => { return true; } +/** + * Processes model results based on type + * + * @param {Array} results + * @param {String} modelType + * + * @return {processedResults} + */ +const processResults = async (results, modelType) => { + switch (modelType){ + case "Entity": + let processedResults = []; + for(let result of results){ + //todo expand conditional checking as checkin object becomes more mature + if(result["checkIn"] !== null) { + result["checkIn"] = result["checkIn"].checkIns[0]; + } + processedResults = [...processedResults, result]; + } + return processedResults; + default: + return results; + }; +} + export default { formatTime, authMiddleware, response, encryptPassword, - validateEmails + validateEmails, + processResults }; diff --git a/swagger.json b/swagger.json index 81f5546d..a6d70448 100644 --- a/swagger.json +++ b/swagger.json @@ -28,7 +28,10 @@ }, { "name" : "contact", "description" : "Operations related to contacts" - } ], + }, { + "name": "csv", + "description": "Operations related to CSV data dumps" + }], "paths" : { "/health" : { "get" : { @@ -702,6 +705,45 @@ } } } + }, + "/csv/{model_type}": { + "get": { + "tags" : [ "csv" ], + "summary" : "returns a full csv data dump based on the model type", + "description" : "By passing the model type, you can dump all of the current data in csv format.", + "parameters" : [ { + "name" : "model_type", + "in" : "path", + "description" : "type of model you want a csv data dump for", + "required" : true, + "style" : "simple", + "explode" : false, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "the csv data dump", + "content" : { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "401" : { + "description" : "Unauthorized" + }, + "422" : { + "description" : "Invalid input" + }, + "500" : { + "description" : "Server error" + } + } + } } }, "components" : {