diff --git a/.circleci/config.yml b/.circleci/config.yml index 00ab761..761c245 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -71,8 +71,6 @@ workflows: branches: only: - dev - - dev-circleci - - feature/shapeup4-cqrs-update2 # Production builds are exectuted only on tagged commits to the # master branch. diff --git a/package-lock.json b/package-lock.json index 39f9593..2f7ef98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,47 +4,45 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@hapi/address": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz", - "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==" - }, "@hapi/hoek": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-6.2.4.tgz", - "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A==" + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" }, - "@hapi/joi": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.0.tgz", - "integrity": "sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ==", + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "requires": { - "@hapi/address": "2.x.x", - "@hapi/hoek": "6.x.x", - "@hapi/marker": "1.x.x", - "@hapi/topo": "3.x.x" + "@hapi/hoek": "^9.0.0" } }, - "@hapi/marker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@hapi/marker/-/marker-1.0.0.tgz", - "integrity": "sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA==" + "@joi/date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@joi/date/-/date-2.1.0.tgz", + "integrity": "sha512-2zN5m0LgxZp/cynHGbzEImVmFIa+n+IOb/Nlw5LX/PLJneeCwG1NbiGw7MvPjsAKUGQK8z31Nn6V6lEN+4fZhg==", + "requires": { + "moment": "2.x.x" + } }, - "@hapi/topo": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.2.tgz", - "integrity": "sha512-r+aumOqJ5QbD6aLPJWqVjMAPsx5pZKz+F5yPqXZ/WWG9JTtHbQqlzrJoknJ0iJxLj9vlXtmpSdjlkszseeG8OA==", + "@sideway/address": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", + "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", "requires": { - "@hapi/hoek": "8.x.x" - }, - "dependencies": { - "@hapi/hoek": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.0.2.tgz", - "integrity": "sha512-O6o6mrV4P65vVccxymuruucb+GhP2zl9NLCG8OdoFRS8BEGw3vwpPp20wpAtpbQQxz1CEUtmxJGgWhjq1XA3qw==" - } + "@hapi/hoek": "^9.0.0" } }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -2402,6 +2400,18 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "joi": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.2.tgz", + "integrity": "sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw==", + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2768,8 +2778,7 @@ "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "optional": true + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "ms": { "version": "2.1.2", diff --git a/package.json b/package.json index 0a2eb85..57f1722 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,13 @@ "superagent": "^5.1.0" }, "dependencies": { - "@hapi/joi": "^15.1.0", + "@joi/date": "^2.1.0", "async-mutex": "^0.2.4", "bluebird": "^3.5.5", "config": "^3.1.0", "dotenv": "^10.0.0", "get-parameter-names": "^0.3.0", + "joi": "^17.4.2", "lodash": "^4.17.20", "no-kafka": "^3.4.3", "tc-core-library-js": "^2.4.1", diff --git a/src/bootstrap.js b/src/bootstrap.js index 6929d7f..979533d 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -1,4 +1,4 @@ -const Joi = require('@hapi/joi') +const Joi = require('joi') const config = require('config') const constants = require('./common/constants') @@ -8,6 +8,7 @@ Joi.rateType = () => Joi.string().valid('hourly', 'daily', 'weekly', 'monthly', Joi.jobStatus = () => Joi.string().valid('sourcing', 'in-review', 'assigned', 'closed', 'cancelled') Joi.jobCandidateStatus = () => Joi.string().valid('open', 'placed', 'selected', 'client rejected - screening', 'client rejected - interview', 'rejected - other', 'cancelled', 'interview', 'topcoder-rejected', 'applied', 'rejected-pre-screen', 'skills-test', 'skills-test', 'phone-screen', 'job-closed', 'offered', 'withdrawn', 'withdrawn-prescreen') Joi.workload = () => Joi.string().valid('full-time', 'fractional') +Joi.jobTag = () => Joi.string().valid('New', '$$$', 'Hot').allow('') Joi.title = () => Joi.string().max(128) // Empty string is not allowed by Joi by default and must be enabled with allow(''). // See https://joi.dev/api/?v=17.3.0#string fro details why it's like this. diff --git a/src/common/logger.js b/src/common/logger.js index 2204596..ac455a0 100644 --- a/src/common/logger.js +++ b/src/common/logger.js @@ -3,7 +3,7 @@ */ const _ = require('lodash') -const Joi = require('@hapi/joi') +const Joi = require('joi') const util = require('util') const config = require('config') const getParams = require('get-parameter-names') diff --git a/src/services/JobCandidateProcessorService.js b/src/services/JobCandidateProcessorService.js index c392d42..5a9d287 100644 --- a/src/services/JobCandidateProcessorService.js +++ b/src/services/JobCandidateProcessorService.js @@ -2,7 +2,7 @@ * Jobcandidate Processor Service */ -const Joi = require('@hapi/joi') +const Joi = require('joi') const logger = require('../common/logger') const helper = require('../common/helper') const constants = require('../common/constants') @@ -74,34 +74,35 @@ async function processUpdate (message, transactionId) { }) } -processUpdate.schema = { - message: Joi.object() - .keys({ - topic: Joi.string().required(), - originator: Joi.string().required(), - timestamp: Joi.date().required(), - 'mime-type': Joi.string().required(), - key: Joi.string().allow(null), - payload: Joi.object() - .keys({ - id: Joi.string().uuid().required(), - jobId: Joi.string().uuid().required(), - userId: Joi.string().uuid().required(), - createdAt: Joi.date().required(), - createdBy: Joi.string().uuid().required(), - updatedAt: Joi.date().allow(null), - viewedByCustomer: Joi.boolean().required(), - updatedBy: Joi.string().uuid().allow(null), - status: Joi.jobCandidateStatus().required(), - externalId: Joi.string().allow(null), - resume: Joi.string().uri().allow(null).allow(''), - remark: Joi.stringAllowEmpty().allow(null) - }) - .required() - }) - .required(), - transactionId: Joi.string().required() -} +processUpdate.schema = Joi.object() + .keys({ + message: Joi.object() + .keys({ + topic: Joi.string().required(), + originator: Joi.string().required(), + timestamp: Joi.date().required(), + 'mime-type': Joi.string().required(), + key: Joi.string().allow(null), + payload: Joi.object() + .keys({ + id: Joi.string().uuid().required(), + jobId: Joi.string().uuid().required(), + userId: Joi.string().uuid().required(), + createdAt: Joi.date().required(), + createdBy: Joi.string().uuid().required(), + updatedAt: Joi.date().allow(null), + viewedByCustomer: Joi.boolean().required(), + updatedBy: Joi.string().uuid().allow(null), + status: Joi.jobCandidateStatus().required(), + externalId: Joi.string().allow(null), + resume: Joi.string().uri().allow(null).allow(''), + remark: Joi.stringAllowEmpty().allow(null) + }) + .required() + }) + .required(), + transactionId: Joi.string().required() + }) module.exports = { processUpdate diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index 02f3b1d..351c123 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -2,7 +2,7 @@ * Job Processor Service */ -const Joi = require('@hapi/joi') +const Joi = require('joi').extend(require('@joi/date')) const logger = require('../common/logger') const helper = require('../common/helper') const constants = require('../common/constants') @@ -50,49 +50,54 @@ async function processCreate (message, transactionId) { }) } -processCreate.schema = { - message: Joi.object() - .keys({ - topic: Joi.string().required(), - originator: Joi.string().required(), - timestamp: Joi.date().required(), - 'mime-type': Joi.string().required(), - payload: Joi.object() - .keys({ - id: Joi.string().uuid().required(), - projectId: Joi.number().integer().required(), - externalId: Joi.string().allow(null), - description: Joi.stringAllowEmpty().allow(null), - title: Joi.title().required(), - startDate: Joi.date().allow(null), - duration: Joi.number().integer().min(1).allow(null), - numPositions: Joi.number().integer().min(1).required(), - resourceType: Joi.stringAllowEmpty().allow(null), - rateType: Joi.rateType().allow(null), - workload: Joi.workload().allow(null), - skills: Joi.array().items(Joi.string().uuid()).required(), - roles: Joi.array().items(Joi.string().uuid()).allow(null), - createdAt: Joi.date().required(), - createdBy: Joi.string().uuid().required(), - updatedAt: Joi.date().allow(null), - updatedBy: Joi.string().uuid().allow(null), - status: Joi.jobStatus().required(), - isApplicationPageActive: Joi.boolean().required(), - minSalary: Joi.number().integer().allow(null), - maxSalary: Joi.number().integer().allow(null), - hoursPerWeek: Joi.number().integer().allow(null), - jobLocation: Joi.stringAllowEmpty().allow(null), - jobTimezone: Joi.stringAllowEmpty().allow(null), - currency: Joi.stringAllowEmpty().allow(null), - roleIds: Joi.array() - .items(Joi.string().uuid().required()) - .allow(null) - }) - .required() - }) - .required(), - transactionId: Joi.string().required() -} +processCreate.schema = Joi.object() + .keys({ + message: Joi.object() + .keys({ + topic: Joi.string().required(), + originator: Joi.string().required(), + timestamp: Joi.date().required(), + 'mime-type': Joi.string().required(), + payload: Joi.object() + .keys({ + id: Joi.string().uuid().required(), + projectId: Joi.number().integer().required(), + externalId: Joi.string().allow(null), + description: Joi.stringAllowEmpty().allow(null), + title: Joi.title().required(), + startDate: Joi.date().format('YYYY-MM-DD').allow(null), + duration: Joi.number().integer().min(1).allow(null), + numPositions: Joi.number().integer().min(1).required(), + resourceType: Joi.stringAllowEmpty().allow(null), + rateType: Joi.rateType().allow(null), + workload: Joi.workload().allow(null), + skills: Joi.array().items(Joi.string().uuid()).required(), + roles: Joi.array().items(Joi.string().uuid()).allow(null), + createdAt: Joi.date().required(), + createdBy: Joi.string().uuid().required(), + updatedAt: Joi.date().allow(null), + updatedBy: Joi.string().uuid().allow(null), + status: Joi.jobStatus().required(), + isApplicationPageActive: Joi.boolean().required(), + minSalary: Joi.number().integer().allow(null), + maxSalary: Joi.number().integer().allow(null), + hoursPerWeek: Joi.number().integer().allow(null), + jobLocation: Joi.stringAllowEmpty().allow(null), + jobTimezone: Joi.stringAllowEmpty().allow(null), + currency: Joi.stringAllowEmpty().allow(null), + roleIds: Joi.array() + .items(Joi.string().uuid().required()) + .allow(null), + showInHotList: Joi.boolean().default(false), + featured: Joi.boolean().default(false), + hotListExcerpt: Joi.stringAllowEmpty().default(''), + jobTag: Joi.jobTag().default('') + }) + .required() + }) + .required(), + transactionId: Joi.string().required() + }) /** * Process update entity message