Skip to content

Commit c241d35

Browse files
Merge pull request #579 from topcoder-platform/dev
[Ready Release] Gigs Listing - RCRM Status Sync
2 parents e465860 + 1a6fd41 commit c241d35

File tree

13 files changed

+297
-10
lines changed

13 files changed

+297
-10
lines changed

data/demo-data.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,7 @@
13251325
"externalId": "300234321",
13261326
"resume": "http://example.com",
13271327
"remark": "excellent",
1328+
"featured": null,
13281329
"createdBy": "00000000-0000-0000-0000-000000000000",
13291330
"updatedBy": "00000000-0000-0000-0000-000000000000",
13301331
"createdAt": "2021-05-09T21:15:02.183Z",

docs/swagger.yaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,18 @@ paths:
213213
schema:
214214
type: boolean
215215
description: When passing true, the API will load all featured and showInHotList jobs at once
216+
- in: query
217+
name: featured
218+
required: false
219+
schema:
220+
type: boolean
221+
description: The featured jobs
222+
- in: query
223+
name: rcrmStatus
224+
required: false
225+
schema:
226+
type: string
227+
enum: ["Open", "On Hold", "Canceled", "Draft", "Closed"]
216228
requestBody:
217229
content:
218230
application/json:
@@ -4122,6 +4134,32 @@ components:
41224134
type: string
41234135
example: "USD"
41244136
description: "the currency of job"
4137+
showInHotList:
4138+
type: boolean
4139+
default: false
4140+
description: "Whether to show job in hot list"
4141+
featured:
4142+
type: boolean
4143+
default: false
4144+
description: "Whether a job is a featured job"
4145+
hotListExcerpt:
4146+
type: string
4147+
default: ''
4148+
description: "A text to show for the hotlist excerpt"
4149+
jobTag:
4150+
type: string
4151+
default: ''
4152+
enum: ["New", "$$$", "Hot", ""]
4153+
description: "the job tag"
4154+
rcrmStatus:
4155+
type: string
4156+
default: null
4157+
enum: [null, "Open", "On Hold", "Canceled", "Draft", "Closed"]
4158+
description: "the job rcrm status"
4159+
rcrmReason:
4160+
type: string
4161+
default: null
4162+
description: "the possible rcrm reason for current status"
41254163
createdAt:
41264164
type: string
41274165
format: date-time
@@ -4241,6 +4279,15 @@ components:
42414279
type: string
42424280
enum: ["", "New", "$$$", "Hot"]
42434281
description: "The tag of a job"
4282+
rcrmStatus:
4283+
type: string
4284+
default: null
4285+
enum: [null, "Open", "On Hold", "Canceled", "Draft", "Closed"]
4286+
description: "the job rcrm status"
4287+
rcrmReason:
4288+
type: string
4289+
default: null
4290+
description: "the possible rcrm reason for current status"
42444291
isApplicationPageActive:
42454292
type: boolean
42464293
default: false
@@ -4797,6 +4844,15 @@ components:
47974844
type: string
47984845
enum: ["", "New", "$$$", "Hot"]
47994846
description: "The tag of a job"
4847+
rcrmStatus:
4848+
type: string
4849+
default: null
4850+
enum: [null, "Open", "On Hold", "Canceled", "Draft", "Closed"]
4851+
description: "the job rcrm status"
4852+
rcrmReason:
4853+
type: string
4854+
default: null
4855+
description: "the possible rcrm reason for current status"
48004856
isApplicationPageActive:
48014857
type: boolean
48024858
default: false

local/kafka-client/topics.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ taas.interview.update
2121
taas.interview.bulkUpdate
2222
external.action.email
2323
taas.action.retry
24-
notifications.action.create
24+
notifications.action.create
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const config = require('config')
2+
3+
/*
4+
* Add rcrm_status, rcrm_reason to the Job model.
5+
type: Sequelize.STRING(255),
6+
defaultValue: null,
7+
allowNull: true
8+
*/
9+
10+
module.exports = {
11+
up: async (queryInterface, Sequelize) => {
12+
const transaction = await queryInterface.sequelize.transaction()
13+
try {
14+
await queryInterface.addColumn({ tableName: 'jobs', schema: config.DB_SCHEMA_NAME }, 'rcrm_status',
15+
{ type: Sequelize.STRING(255), allowNull: true, defaultValue: null },
16+
{ transaction })
17+
await queryInterface.addColumn({ tableName: 'jobs', schema: config.DB_SCHEMA_NAME }, 'rcrm_reason',
18+
{ type: Sequelize.STRING(255), allowNull: true, defaultValue: null },
19+
{ transaction })
20+
await transaction.commit()
21+
} catch (err) {
22+
await transaction.rollback()
23+
throw err
24+
}
25+
},
26+
down: async (queryInterface, Sequelize) => {
27+
const transaction = await queryInterface.sequelize.transaction()
28+
try {
29+
await queryInterface.removeColumn({ tableName: 'jobs', schema: config.DB_SCHEMA_NAME }, 'rcrm_status', { transaction })
30+
await queryInterface.removeColumn({ tableName: 'jobs', schema: config.DB_SCHEMA_NAME }, 'rcrm_reason', { transaction })
31+
await transaction.commit()
32+
} catch (err) {
33+
await transaction.rollback()
34+
throw err
35+
}
36+
}
37+
}

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
"demo-payment": "node scripts/demo-payment",
3434
"migrate:backup-withdrawn": "node scripts/withdrawn-migration/backup.js",
3535
"migrate:migration-withdrawn": "node scripts/withdrawn-migration/migration.js",
36-
"migrate:restore-withdrawn": "node scripts/withdrawn-migration/restore.js"
36+
"migrate:restore-withdrawn": "node scripts/withdrawn-migration/restore.js",
37+
"migrate:backup-rcrm-status": "node scripts/job-rcrm-status-migration/backup.js",
38+
"migrate:migration-rcrm-status": "node scripts/job-rcrm-status-migration/migration.js",
39+
"migrate:restore-rcrm-status": "node scripts/job-rcrm-status-migration/restore.js"
3740
},
3841
"keywords": [],
3942
"author": "",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Back up the jobs that we will update it's status
3+
*/
4+
const fs = require('fs')
5+
const path = require('path')
6+
const request = require('superagent')
7+
const logger = require('../../src/common/logger')
8+
9+
const currentStep = 'Backup'
10+
11+
async function backup () {
12+
logger.info({ component: currentStep, message: '*************************** Backup process started ***************************' })
13+
const filePath = path.join(__dirname, '/temp/')
14+
if (fs.existsSync(filePath)) {
15+
fs.rmdirSync(filePath, { recursive: true })
16+
}
17+
fs.mkdirSync(filePath)
18+
let { body: jobs } = await request.get('https://www.topcoder-dev.com/api/recruit/jobs?job_status=1')
19+
jobs = jobs.map((item) => item.slug)
20+
if (jobs && jobs.length > 0) {
21+
try {
22+
fs.writeFileSync(filePath + 'jobs-backup.json', JSON.stringify(
23+
jobs
24+
))
25+
logger.info({ component: `${currentStep} Sub`, message: `There are ${jobs.length} jobs that need to be updated` })
26+
} catch (err) {
27+
logger.error({ component: currentStep, message: err.message })
28+
process.exit(1)
29+
}
30+
}
31+
logger.info({ component: `${currentStep}`, message: `Report: there are ${jobs.length} jobs in total` })
32+
logger.info({ component: currentStep, message: '*************************** Backup process finished ***************************' })
33+
}
34+
35+
backup().then(() => {
36+
logger.info({ component: currentStep, message: 'Execution Finished!' })
37+
process.exit()
38+
}).catch(err => {
39+
logger.error(err.message)
40+
process.exit(1)
41+
})
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Migration the job rcrm status into Open status
3+
*/
4+
const fs = require('fs')
5+
const path = require('path')
6+
const { Job } = require('../../src/models')
7+
const logger = require('../../src/common/logger')
8+
9+
const currentStep = 'Migration'
10+
11+
async function migration () {
12+
logger.info({ component: currentStep, message: '*************************** Migration process started ***************************' })
13+
const filePath = path.join(__dirname, '/temp/')
14+
const files = []
15+
fs.readdirSync(filePath).forEach(async (file) => {
16+
files.push(`${filePath}${file}`)
17+
})
18+
let totalSum = 0
19+
for (let j = 0; j < files.length; j++) {
20+
const data = fs.readFileSync(files[j], 'utf-8')
21+
const rcrmIds = JSON.parse(data)
22+
let summary = 0
23+
for (let i = 0; i < rcrmIds.length; i++) {
24+
const jbs = await Job.findAll({
25+
where: { externalId: rcrmIds[i] }
26+
})
27+
for (let j = 0; j < jbs.length; j++) {
28+
if (jbs[j]) {
29+
const oldStatus = jbs[j].rcrmStatus
30+
const updated = await jbs[j].update({ rcrmStatus: 'Open' })
31+
summary++
32+
totalSum++
33+
logger.info({ component: currentStep, message: `job with rcrmId ${rcrmIds[i]} status changed from ${oldStatus} to ${updated.rcrmStatus}` })
34+
}
35+
}
36+
};
37+
logger.info({ component: `${currentStep} Sub`, message: `Updated ${summary} jobs from ${files[j]}` })
38+
}
39+
logger.info({ component: currentStep, message: `Report: Totally Updated ${totalSum} jobs` })
40+
logger.info({ component: currentStep, message: '*************************** Migration process finished ***************************' })
41+
}
42+
43+
migration().then(() => {
44+
logger.info({ component: currentStep, message: 'Execution Finished!' })
45+
process.exit()
46+
}).catch(err => {
47+
logger.error(err.message)
48+
process.exit(1)
49+
})
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Restore the job rcrm status into Open status
3+
*/
4+
const fs = require('fs')
5+
const path = require('path')
6+
const { Job } = require('../../src/models')
7+
const logger = require('../../src/common/logger')
8+
9+
const currentStep = 'Restore'
10+
11+
async function restore () {
12+
logger.info({ component: currentStep, message: '*************************** Restore process started ***************************' })
13+
const filePath = path.join(__dirname, '/temp/')
14+
const files = []
15+
fs.readdirSync(filePath).forEach(async (file) => {
16+
files.push(`${filePath}${file}`)
17+
})
18+
let totalSum = 0
19+
for (let j = 0; j < files.length; j++) {
20+
const data = fs.readFileSync(files[j], 'utf-8')
21+
const rcrmIds = JSON.parse(data)
22+
let summary = 0
23+
for (let i = 0; i < rcrmIds.length; i++) {
24+
const jbs = await Job.findAll({
25+
where: { externalId: rcrmIds[i] }
26+
})
27+
for (let j = 0; j < jbs.length; j++) {
28+
if (jbs[j]) {
29+
const oldStatus = jbs[j].rcrmStatus
30+
const updated = await jbs[j].update({ rcrmStatus: null })
31+
summary++
32+
totalSum++
33+
logger.info({ component: currentStep, message: `job with rcrmId ${rcrmIds[i]} status changed from ${oldStatus} to ${updated.rcrmStatus}` })
34+
}
35+
}
36+
};
37+
logger.info({ component: `${currentStep} Sub`, message: `Updated ${summary} jobs from ${files[j]}` })
38+
}
39+
logger.info({ component: currentStep, message: `Report: Totally Restored ${totalSum} jobs` })
40+
logger.info({ component: currentStep, message: '*************************** Restore process finished ***************************' })
41+
}
42+
43+
restore().then(() => {
44+
logger.info({ component: currentStep, message: 'Execution Finished!' })
45+
process.exit()
46+
}).catch(err => {
47+
logger.error(err.message)
48+
process.exit(1)
49+
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["90269852","28960960","16341500556800013350dQL","16341323722130013350Qgs","16341323715070013350yCX","16341501858830013350JSx","16342073365140013350Omh","16342071086360013350TKd","29014265","16341982292150013350DhE","16341851836400013350YSd","16341851823530013350OHa","16341323716640013350BFn","16341517864620013350LvZ","16341438759150013350CTj","16341414354520013350czx","16329389793410013350nhr","16341285133710013350gRv","16327915384700013350wjq","16322342157030013350thK","16340504449290013350Zmk","16336199677990013350hWP","16340663860380013350dkg","16323945983630013350VIn","16340663745860013350Ogp","16340521190520013350Zyo","16329256769300013350wOD","16330142450080013350Zud","16336147040350013350Nbe","16335218110630009830oSa","16328384519390013350hzK","16337227842100013350BDn","16328401153230013350dVH","16339568564580013350cxO","16337126130130013350GNX","16337229047900013350rlK","16339461887230013350pHA","16339455520130013350SMw","16292946209270013350cqL","16317343900830013350iSB","16334323145940013350bqN","16333532888560013350VfJ","16335231874280013350PsN","16335233245550013350ybF","16335365496710013350mdw","16324274043560013350per","28968572","16328235118630013350TUH","16329413634180013350cbO","89425274","16322224121530013350BxF","16335010800170013350OlD","16335010785580013350ZMW","16335010794140013350qSN","16335010771830013350kvN","16335010773590013350kyi","16329269383370013350pcK","16334453262680013350ksT","16317088129440013350Yuq","16333604284300013350scM","16334117377520013350lxQ","16334117503830013350mot","16334040093120013350uQK","16333472255660013350DMW","16322834774440013350qgN","16322398868710013350TVc","16333463496610013350hPf","16333296533550013350VMv","16311102743050013350UOQ","16305004931790013350nDf","16329484262990013350Lxj","16329780377000013350gjy","16321575158770013350aMr","16330154680980013350guh","16330154680330013350xSz","16330153298270013350azs","16317282228550013350KNM","16329976194830013350YeO","16329926004110013350tBA","16329780351410013350mLA","16305004990960013350Ssa","16325262321460013350SVA","16311098213960013350dOG","89264852","16322413567270013350DGr","16305004975190013350PFT","16309630704830013350hEg","16328129817130013350NAX","16328127653330013350DdA","16328123904580013350LUi","16328103721410013350tQw","16328099924470013350xAs","90068402","16327519095440013350Pxc","16327519083280013350ehu","16327406515900013350pkn","16324784697460013350zYO","16327120198060013350ncx","16326943991890013350CEP","27288460","16311191494770013350NUc","16313030794420013350jid","16313049677110013350DaN","16311326832280013350lHd","16323409561830013350sZU","16323378537470013350LEP","16312171350470013350JFb","16322398849240013350gPZ","16318012800890013350XTH","16323155626160013350sIH","28317595","16318000891270013350pVC","16322398874030013350dvM","29006647","16315538849780013350xOe","16310329298030013350vqT","16311345128210013350uOw","16312910846980013350yXL","16319302023020013350VjQ","16318858946340013350azO","16318858943670013350UyO","16318065232030013350ocm","16317263340200013350OAu","16318005347030013350xIY","89358414","16317823615620013350XTK","16304287461100013350mlf","16317340318160013350Tvh","90162384","16316425217580013350jtR","16317111609390013350kBm","16313011847990013350euT","16316739298570013350ubh","16316427345940013350FdR","16316254338250013350pnL","16315761396170013350NdW","16315527065980013350goJ","16315527103010013350OJR","16315527070820013350lNq","16315377284630013350kKy","16311282358380013350yvA","16311123863240013350poV","16311065501620013350xXk","16297520948230013350jsO","29381105","29121022","16297515193190013350yKq","16307003081530013350IRF","16298349408110013350fVu","16298344596880013350BkO","16306692819950013350PDG","16306692838930013350ZSc","16305973203140013350VLM","16305382326930013350ZIQ","16287824631380013350wvk","90296729","16303059379040013350mEr","16305210643780013350wHi","16298350433530013350pao","16300042451840013350bRI","28604324","29029504","29105759","16285320575270013350CGO","16292061450370013350IBs","29235622","16291317250860013350FZU","16292936844360013350FUf","28877294","90202677","90216110","90417725","29212684","29365774","16286918867350013350JMe","16285323789010013350Eaf","29205040","26759080","16297498617830013350rVR","16297359818350013350zUS","29059994","90471527","16285337043140013350ZKp","16281924024020013350syz","90148955","25996360","89385155","89371784","89518920","89505539","89438649","89398527","29373439"]

src/bootstrap.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Joi.page = () => Joi.number().integer().min(1).default(1)
1313
Joi.perPage = () => Joi.number().integer().min(1).default(20)
1414
Joi.rateType = () => Joi.string().valid('hourly', 'daily', 'weekly', 'monthly', 'annual')
1515
Joi.jobStatus = () => Joi.string().valid('sourcing', 'in-review', 'assigned', 'closed', 'cancelled')
16+
Joi.jobRcrmStatus = () => Joi.string().valid('Open', 'On Hold', 'Canceled', 'Draft', 'Closed').allow(null)
1617
Joi.jobTag = () => Joi.string().valid('New', '$$$', 'Hot').allow('')
1718
Joi.resourceBookingStatus = () => Joi.string().valid('placed', 'closed', 'cancelled')
1819
Joi.workload = () => Joi.string().valid('full-time', 'fractional')

src/models/Job.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,18 @@ module.exports = (sequelize) => {
164164
allowNull: true,
165165
defaultValue: ''
166166
},
167+
rcrmStatus: {
168+
field: 'rcrm_status',
169+
type: Sequelize.STRING(255),
170+
allowNull: true,
171+
defaultValue: null
172+
},
173+
rcrmReason: {
174+
field: 'rcrm_reason',
175+
type: Sequelize.STRING(255),
176+
allowNull: true,
177+
defaultValue: null
178+
},
167179
createdBy: {
168180
field: 'created_by',
169181
type: Sequelize.UUID,

0 commit comments

Comments
 (0)