From 181960f7c4d34e1512822725e24d963f3197ca20 Mon Sep 17 00:00:00 2001 From: imcaizheng Date: Tue, 26 Jan 2021 15:17:32 +0800 Subject: [PATCH 1/8] include a new duration field --- src/scripts/createIndex.js | 2 ++ src/services/JobProcessorService.js | 2 ++ src/services/ResourceBookingProcessorService.js | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/scripts/createIndex.js b/src/scripts/createIndex.js index 4edce30..50f7ba1 100644 --- a/src/scripts/createIndex.js +++ b/src/scripts/createIndex.js @@ -21,6 +21,7 @@ async function createIndex () { title: { type: 'text' }, startDate: { type: 'date' }, endDate: { type: 'date' }, + duration: { type: 'integer' }, numPositions: { type: 'integer' }, resourceType: { type: 'keyword' }, rateType: { type: 'keyword' }, @@ -64,6 +65,7 @@ async function createIndex () { status: { type: 'keyword' }, startDate: { type: 'date' }, endDate: { type: 'date' }, + duration: { type: 'integer' }, memberRate: { type: 'float' }, customerRate: { type: 'float' }, rateType: { type: 'keyword' }, diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index 72131ed..dbfce90 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -74,6 +74,7 @@ processCreate.schema = { title: Joi.title().required(), startDate: Joi.date(), endDate: Joi.date(), + duration: Joi.number().integer().min(1), numPositions: Joi.number().integer().min(1).required(), resourceType: Joi.string(), rateType: Joi.rateType(), @@ -123,6 +124,7 @@ processUpdate.schema = { title: Joi.title(), startDate: Joi.date(), endDate: Joi.date(), + duration: Joi.number().integer().min(1), numPositions: Joi.number().integer().min(1), resourceType: Joi.string(), rateType: Joi.rateType(), diff --git a/src/services/ResourceBookingProcessorService.js b/src/services/ResourceBookingProcessorService.js index 23b1de3..f7a77b6 100644 --- a/src/services/ResourceBookingProcessorService.js +++ b/src/services/ResourceBookingProcessorService.js @@ -40,6 +40,7 @@ processCreate.schema = { jobId: Joi.string().uuid(), startDate: Joi.date(), endDate: Joi.date(), + duration: Joi.number().integer().min(1), memberRate: Joi.number(), customerRate: Joi.number(), rateType: Joi.rateType().required(), @@ -82,6 +83,7 @@ processUpdate.schema = { jobId: Joi.string().uuid(), startDate: Joi.date(), endDate: Joi.date(), + duration: Joi.number().integer().min(1), memberRate: Joi.number(), customerRate: Joi.number(), rateType: Joi.rateType(), From 8bfab60820b6bee1227fab48da3b99a29f224232 Mon Sep 17 00:00:00 2001 From: maxceem Date: Wed, 27 Jan 2021 10:38:31 +0200 Subject: [PATCH 2/8] Revert "include a new duration field" --- src/scripts/createIndex.js | 2 -- src/services/JobProcessorService.js | 2 -- src/services/ResourceBookingProcessorService.js | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/scripts/createIndex.js b/src/scripts/createIndex.js index 50f7ba1..4edce30 100644 --- a/src/scripts/createIndex.js +++ b/src/scripts/createIndex.js @@ -21,7 +21,6 @@ async function createIndex () { title: { type: 'text' }, startDate: { type: 'date' }, endDate: { type: 'date' }, - duration: { type: 'integer' }, numPositions: { type: 'integer' }, resourceType: { type: 'keyword' }, rateType: { type: 'keyword' }, @@ -65,7 +64,6 @@ async function createIndex () { status: { type: 'keyword' }, startDate: { type: 'date' }, endDate: { type: 'date' }, - duration: { type: 'integer' }, memberRate: { type: 'float' }, customerRate: { type: 'float' }, rateType: { type: 'keyword' }, diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index dbfce90..72131ed 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -74,7 +74,6 @@ processCreate.schema = { title: Joi.title().required(), startDate: Joi.date(), endDate: Joi.date(), - duration: Joi.number().integer().min(1), numPositions: Joi.number().integer().min(1).required(), resourceType: Joi.string(), rateType: Joi.rateType(), @@ -124,7 +123,6 @@ processUpdate.schema = { title: Joi.title(), startDate: Joi.date(), endDate: Joi.date(), - duration: Joi.number().integer().min(1), numPositions: Joi.number().integer().min(1), resourceType: Joi.string(), rateType: Joi.rateType(), diff --git a/src/services/ResourceBookingProcessorService.js b/src/services/ResourceBookingProcessorService.js index f7a77b6..23b1de3 100644 --- a/src/services/ResourceBookingProcessorService.js +++ b/src/services/ResourceBookingProcessorService.js @@ -40,7 +40,6 @@ processCreate.schema = { jobId: Joi.string().uuid(), startDate: Joi.date(), endDate: Joi.date(), - duration: Joi.number().integer().min(1), memberRate: Joi.number(), customerRate: Joi.number(), rateType: Joi.rateType().required(), @@ -83,7 +82,6 @@ processUpdate.schema = { jobId: Joi.string().uuid(), startDate: Joi.date(), endDate: Joi.date(), - duration: Joi.number().integer().min(1), memberRate: Joi.number(), customerRate: Joi.number(), rateType: Joi.rateType(), From 96bcad1533e4a4791b23508f888761d5ea4cac02 Mon Sep 17 00:00:00 2001 From: imcaizheng Date: Thu, 4 Feb 2021 13:59:15 +0800 Subject: [PATCH 3/8] Include the `id` field inside the body of a document --- src/services/JobCandidateProcessorService.js | 4 ++-- src/services/JobProcessorService.js | 4 ++-- src/services/ResourceBookingProcessorService.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/services/JobCandidateProcessorService.js b/src/services/JobCandidateProcessorService.js index 0936815..837e42b 100644 --- a/src/services/JobCandidateProcessorService.js +++ b/src/services/JobCandidateProcessorService.js @@ -80,7 +80,7 @@ async function processCreate (message, transactionId) { index: config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), id: jobcandidate.id, transactionId, - body: _.omit(jobcandidate, 'id'), + body: jobcandidate, refresh: constants.esRefreshOption }) } @@ -117,7 +117,7 @@ async function processUpdate (message, transactionId) { id: data.id, transactionId, body: { - doc: _.omit(data, ['id']) + doc: data }, refresh: constants.esRefreshOption }) diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index 72131ed..9350e52 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -51,7 +51,7 @@ async function processCreate (message, transactionId) { index: config.get('esConfig.ES_INDEX_JOB'), id: job.id, transactionId, - body: _.omit(job, 'id'), + body: job, refresh: constants.esRefreshOption }) await postMessageToZapier({ @@ -99,7 +99,7 @@ async function processUpdate (message, transactionId) { id: data.id, transactionId, body: { - doc: _.omit(data, ['id']) + doc: data }, refresh: constants.esRefreshOption }) diff --git a/src/services/ResourceBookingProcessorService.js b/src/services/ResourceBookingProcessorService.js index 23b1de3..d7264bf 100644 --- a/src/services/ResourceBookingProcessorService.js +++ b/src/services/ResourceBookingProcessorService.js @@ -22,7 +22,7 @@ async function processCreate (message, transactionId) { index: config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), id: resourcebooking.id, transactionId, - body: _.omit(resourcebooking, 'id'), + body: resourcebooking, refresh: constants.esRefreshOption }) } @@ -63,7 +63,7 @@ async function processUpdate (message, transactionId) { id: data.id, transactionId, body: { - doc: _.omit(data, ['id']) + doc: data }, refresh: constants.esRefreshOption }) From 7baecca493412376998bbaa0ddfb82b460e9b62f Mon Sep 17 00:00:00 2001 From: maxceem Date: Thu, 4 Feb 2021 15:31:53 +0200 Subject: [PATCH 4/8] fix: allow empty "description" and "resourceType" this is done to make it easier creating UI for editing these fields, as usually forms send empty value instead of "null" or "undefined" --- src/bootstrap.js | 4 ++++ src/services/JobProcessorService.js | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bootstrap.js b/src/bootstrap.js index f49e5b3..d6cefec 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -9,6 +9,10 @@ Joi.jobStatus = () => Joi.string().valid('sourcing', 'in-review', 'assigned', 'c Joi.jobCandidateStatus = () => Joi.string().valid('open', 'selected', 'shortlist', 'rejected', 'cancelled') Joi.workload = () => Joi.string().valid('full-time', 'fractional') 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. +// In many cases we would like to allow empty string to make it easier to create UI for editing data. +Joi.stringAllowEmpty = () => Joi.string().allow('') const zapierSwitch = Joi.string().label('ZAPIER_SWITCH').valid(...Object.values(constants.Zapier.Switch)) diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index 9350e52..37ab5c0 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -70,12 +70,12 @@ processCreate.schema = { id: Joi.string().uuid().required(), projectId: Joi.number().integer().required(), externalId: Joi.string(), - description: Joi.string(), + description: Joi.stringAllowEmpty(), title: Joi.title().required(), startDate: Joi.date(), endDate: Joi.date(), numPositions: Joi.number().integer().min(1).required(), - resourceType: Joi.string(), + resourceType: Joi.stringAllowEmpty(), rateType: Joi.rateType(), workload: Joi.workload(), skills: Joi.array().items(Joi.string().uuid()).required(), @@ -119,12 +119,12 @@ processUpdate.schema = { id: Joi.string().uuid().required(), projectId: Joi.number().integer(), externalId: Joi.string(), - description: Joi.string(), + description: Joi.stringAllowEmpty(), title: Joi.title(), startDate: Joi.date(), endDate: Joi.date(), numPositions: Joi.number().integer().min(1), - resourceType: Joi.string(), + resourceType: Joi.stringAllowEmpty(), rateType: Joi.rateType(), workload: Joi.workload(), skills: Joi.array().items(Joi.string().uuid()), From a86c9781b0629595695b8e25b32c0b845887f1be Mon Sep 17 00:00:00 2001 From: imcaizheng Date: Sat, 6 Feb 2021 15:14:26 +0800 Subject: [PATCH 5/8] Update joi schemas to allow null values --- src/services/JobCandidateProcessorService.js | 24 ++--------- src/services/JobProcessorService.js | 43 +++++-------------- .../ResourceBookingProcessorService.js | 36 ++++------------ 3 files changed, 22 insertions(+), 81 deletions(-) diff --git a/src/services/JobCandidateProcessorService.js b/src/services/JobCandidateProcessorService.js index 837e42b..ed4fdd1 100644 --- a/src/services/JobCandidateProcessorService.js +++ b/src/services/JobCandidateProcessorService.js @@ -97,8 +97,10 @@ processCreate.schema = { userId: Joi.string().uuid().required(), createdAt: Joi.date().required(), createdBy: Joi.string().uuid().required(), + updatedAt: Joi.date().allow(null), + updatedBy: Joi.string().uuid().allow(null), status: Joi.jobCandidateStatus().required(), - externalId: Joi.string(), + externalId: Joi.string().allow(null), resume: Joi.string().uri() }).required() }).required(), @@ -127,25 +129,7 @@ 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(), - payload: Joi.object().keys({ - id: Joi.string().uuid(), - jobId: Joi.string().uuid(), - userId: Joi.string().uuid(), - status: Joi.jobCandidateStatus(), - externalId: Joi.string(), - resume: Joi.string().uri(), - updatedAt: Joi.date(), - updatedBy: Joi.string().uuid() - }).required() - }).required(), - transactionId: Joi.string().required() -} +processUpdate.schema = processCreate.schema /** * Process delete entity message diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index 37ab5c0..b12e2fa 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -69,18 +69,20 @@ processCreate.schema = { payload: Joi.object().keys({ id: Joi.string().uuid().required(), projectId: Joi.number().integer().required(), - externalId: Joi.string(), - description: Joi.stringAllowEmpty(), + externalId: Joi.string().allow(null), + description: Joi.stringAllowEmpty().allow(null), title: Joi.title().required(), - startDate: Joi.date(), - endDate: Joi.date(), + startDate: Joi.date().allow(null), + endDate: Joi.date().allow(null), numPositions: Joi.number().integer().min(1).required(), - resourceType: Joi.stringAllowEmpty(), - rateType: Joi.rateType(), - workload: Joi.workload(), + resourceType: Joi.stringAllowEmpty().allow(null), + rateType: Joi.rateType().allow(null), + workload: Joi.workload().allow(null), skills: Joi.array().items(Joi.string().uuid()).required(), createdAt: Joi.date().required(), createdBy: Joi.string().uuid().required(), + updatedAt: Joi.date().allow(null), + updatedBy: Joi.string().uuid().allow(null), status: Joi.jobStatus().required() }).required() }).required(), @@ -109,32 +111,7 @@ 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(), - payload: Joi.object().keys({ - id: Joi.string().uuid().required(), - projectId: Joi.number().integer(), - externalId: Joi.string(), - description: Joi.stringAllowEmpty(), - title: Joi.title(), - startDate: Joi.date(), - endDate: Joi.date(), - numPositions: Joi.number().integer().min(1), - resourceType: Joi.stringAllowEmpty(), - rateType: Joi.rateType(), - workload: Joi.workload(), - skills: Joi.array().items(Joi.string().uuid()), - status: Joi.jobStatus(), - updatedAt: Joi.date(), - updatedBy: Joi.string().uuid() - }).required() - }).required(), - transactionId: Joi.string().required() -} +processUpdate.schema = processCreate.schema /** * Process delete entity message diff --git a/src/services/ResourceBookingProcessorService.js b/src/services/ResourceBookingProcessorService.js index d7264bf..48b82c2 100644 --- a/src/services/ResourceBookingProcessorService.js +++ b/src/services/ResourceBookingProcessorService.js @@ -37,14 +37,16 @@ processCreate.schema = { id: Joi.string().uuid().required(), projectId: Joi.number().integer().required(), userId: Joi.string().uuid().required(), - jobId: Joi.string().uuid(), - startDate: Joi.date(), - endDate: Joi.date(), - memberRate: Joi.number(), - customerRate: Joi.number(), + jobId: Joi.string().uuid().allow(null), + startDate: Joi.date().allow(null), + endDate: Joi.date().allow(null), + memberRate: Joi.number().allow(null), + customerRate: Joi.number().allow(null), rateType: Joi.rateType().required(), createdAt: Joi.date().required(), createdBy: Joi.string().uuid().required(), + updatedAt: Joi.date().allow(null), + updatedBy: Joi.string().uuid().allow(null), status: Joi.jobStatus().required() }).required() }).required(), @@ -69,29 +71,7 @@ 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(), - payload: Joi.object().keys({ - id: Joi.string().uuid().required(), - projectId: Joi.number().integer(), - userId: Joi.string().uuid(), - jobId: Joi.string().uuid(), - startDate: Joi.date(), - endDate: Joi.date(), - memberRate: Joi.number(), - customerRate: Joi.number(), - rateType: Joi.rateType(), - status: Joi.jobStatus(), - updatedAt: Joi.date(), - updatedBy: Joi.string().uuid() - }).required() - }).required(), - transactionId: Joi.string().required() -} +processUpdate.schema = processCreate.schema /** * Process delete entity message From 02ce93e5fb27db9f466b1fbf94eaa1a7dcb29108 Mon Sep 17 00:00:00 2001 From: maxceem Date: Sun, 7 Feb 2021 10:51:13 +0200 Subject: [PATCH 6/8] fix: allow null for "resume" --- src/services/JobCandidateProcessorService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/JobCandidateProcessorService.js b/src/services/JobCandidateProcessorService.js index ed4fdd1..b994add 100644 --- a/src/services/JobCandidateProcessorService.js +++ b/src/services/JobCandidateProcessorService.js @@ -101,7 +101,7 @@ processCreate.schema = { updatedBy: Joi.string().uuid().allow(null), status: Joi.jobCandidateStatus().required(), externalId: Joi.string().allow(null), - resume: Joi.string().uri() + resume: Joi.string().uri().allow(null), }).required() }).required(), transactionId: Joi.string().required() From d4acb50643f85b6ca0c446b64f9ffef7705abfbd Mon Sep 17 00:00:00 2001 From: imcaizheng Date: Wed, 10 Feb 2021 02:59:54 +0800 Subject: [PATCH 7/8] Remove `endDate` from Job and add `duration` to Job --- src/scripts/createIndex.js | 1 - src/services/JobCandidateProcessorService.js | 3 +-- src/services/JobProcessorService.js | 3 +-- src/services/ResourceBookingProcessorService.js | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/scripts/createIndex.js b/src/scripts/createIndex.js index 4edce30..865b0bc 100644 --- a/src/scripts/createIndex.js +++ b/src/scripts/createIndex.js @@ -20,7 +20,6 @@ async function createIndex () { description: { type: 'text' }, title: { type: 'text' }, startDate: { type: 'date' }, - endDate: { type: 'date' }, numPositions: { type: 'integer' }, resourceType: { type: 'keyword' }, rateType: { type: 'keyword' }, diff --git a/src/services/JobCandidateProcessorService.js b/src/services/JobCandidateProcessorService.js index b994add..3d0243c 100644 --- a/src/services/JobCandidateProcessorService.js +++ b/src/services/JobCandidateProcessorService.js @@ -2,7 +2,6 @@ * Jobcandidate Processor Service */ -const _ = require('lodash') const Joi = require('@hapi/joi') const logger = require('../common/logger') const helper = require('../common/helper') @@ -101,7 +100,7 @@ processCreate.schema = { updatedBy: Joi.string().uuid().allow(null), status: Joi.jobCandidateStatus().required(), externalId: Joi.string().allow(null), - resume: Joi.string().uri().allow(null), + resume: Joi.string().uri().allow(null) }).required() }).required(), transactionId: Joi.string().required() diff --git a/src/services/JobProcessorService.js b/src/services/JobProcessorService.js index b12e2fa..a2e35a1 100644 --- a/src/services/JobProcessorService.js +++ b/src/services/JobProcessorService.js @@ -2,7 +2,6 @@ * Job Processor Service */ -const _ = require('lodash') const Joi = require('@hapi/joi') const logger = require('../common/logger') const helper = require('../common/helper') @@ -73,7 +72,7 @@ processCreate.schema = { description: Joi.stringAllowEmpty().allow(null), title: Joi.title().required(), startDate: Joi.date().allow(null), - endDate: 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), diff --git a/src/services/ResourceBookingProcessorService.js b/src/services/ResourceBookingProcessorService.js index 48b82c2..964f4d0 100644 --- a/src/services/ResourceBookingProcessorService.js +++ b/src/services/ResourceBookingProcessorService.js @@ -2,7 +2,6 @@ * ResourceBooking Processor Service */ -const _ = require('lodash') const Joi = require('@hapi/joi') const logger = require('../common/logger') const helper = require('../common/helper') From 5b0985dd9f74fcd42dc484279954c67e123083a7 Mon Sep 17 00:00:00 2001 From: imcaizheng Date: Wed, 10 Feb 2021 23:23:22 +0800 Subject: [PATCH 8/8] add duration to ES mapping for job --- src/scripts/createIndex.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripts/createIndex.js b/src/scripts/createIndex.js index 865b0bc..45cca2e 100644 --- a/src/scripts/createIndex.js +++ b/src/scripts/createIndex.js @@ -20,6 +20,7 @@ async function createIndex () { description: { type: 'text' }, title: { type: 'text' }, startDate: { type: 'date' }, + duration: { type: 'integer' }, numPositions: { type: 'integer' }, resourceType: { type: 'keyword' }, rateType: { type: 'keyword' },