Skip to content

Feature/payment scheduler #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c7a47a2
Payments - Batch Endpoints
xxcxy May 26, 2021
5ce9aca
fix: added new 'offered' status
sushilshinde May 27, 2021
1db6efc
Merge pull request #60 from topcoder-platform/statuses-change
sushilshinde May 27, 2021
7370849
api-updates challenge:30186701
May 29, 2021
bfd4d48
Batch Payments - Part 1 - Scheduler
xxcxy May 29, 2021
f4e193d
feat(job-processor): accept `roles` array
cagdas001 May 29, 2021
1836259
Merge pull request #61 from cagdas001/feature/role-intake
nikolay83 May 29, 2021
4b20e8e
fix: resource booking search issues
eisbilir May 30, 2021
97866e2
role endpoint added
eisbilir May 31, 2021
ec14608
Merge pull request #63 from eisbilir/feature/roles-backend-repost
nikolay83 May 31, 2021
5da339c
Merge remote-tracking branch 'upstream/dev' into dev
eisbilir May 31, 2021
4a24d73
Merge pull request #62 from eisbilir/dev
maxceem Jun 1, 2021
cf38c92
Merge branch 'dev' into feature/api-updates
sushilshinde Jun 1, 2021
d8e88a9
Merge pull request #64 from topcoder-platform/feature/api-updates
sushilshinde Jun 1, 2021
5a80f8a
fix: allow null for new fields
sushilshinde Jun 1, 2021
1fcb339
Merge pull request #65 from topcoder-platform/feature/api-updates
sushilshinde Jun 1, 2021
ae9be19
Merge pull request #66 from xxcxy/feature/batch-payments
maxceem Jun 2, 2021
c723de9
Merge branch 'dev' into feature/batch-payments
maxceem Jun 2, 2021
32cf10b
Merge pull request #67 from topcoder-platform/feature/batch-payments
nkumar-topcoder Jun 3, 2021
c0cfe81
Merge branch 'dev' of https://github.com/topcoder-platform/taas-es-pr…
xxcxy Jun 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ The following parameters can be set in config files or in env variables:
- `topics.TAAS_INTERVIEW_REQUEST_TOPIC`: the request interview entity Kafka message topic
- `topics.TAAS_INTERVIEW_UPDATE_TOPIC`: the update interview entity Kafka message topic
- `topics.TAAS_INTERVIEW_BULK_UPDATE_TOPIC`: the bulk update interview entity Kafka message topic
- `topics.TAAS_ROLE_CREATE_TOPIC`: the create role entity Kafka message topic
- `topics.TAAS_ROLE_UPDATE_TOPIC`: the update role entity Kafka message topic
- `topics.TAAS_ROLE_DELETE_TOPIC`: the delete role entity Kafka message topic
- `esConfig.HOST`: Elasticsearch host
- `esConfig.AWS_REGION`: The Amazon region to use when using AWS Elasticsearch service
- `esConfig.ELASTICCLOUD.id`: The elastic cloud id, if your elasticsearch instance is hosted on elastic cloud. DO NOT provide a value for ES_HOST if you are using this
Expand All @@ -46,6 +49,7 @@ The following parameters can be set in config files or in env variables:
- `esConfig.ES_INDEX_JOB`: the index name for job
- `esConfig.ES_INDEX_JOB_CANDIDATE`: the index name for job candidate
- `esConfig.ES_INDEX_RESOURCE_BOOKING`: the index name for resource booking
- `esConfig.ES_INDEX_ROLE`: the index name for role

- `auth0.AUTH0_URL`: Auth0 URL, used to get TC M2M token
- `auth0.AUTH0_AUDIENCE`: Auth0 audience, used to get TC M2M token
Expand Down
12 changes: 9 additions & 3 deletions VERIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Create documents in ES

- Run the following commands to create `Job`, `JobCandidate`, `Interview`, `ResourceBooking`, `WorkPeriod`, `WorkPeriodPayment` documents in ES.
- Run the following commands to create `Job`, `JobCandidate`, `Interview`, `ResourceBooking`, `WorkPeriod`, `WorkPeriodPayment`, `Role` documents in ES.

``` bash
# for Job
Expand All @@ -17,12 +17,14 @@
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.workperiod.create < test/messages/taas.workperiod.create.event.json
# for WorkPeriodPayment
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.workperiodpayment.create < test/messages/taas.workperiodpayment.create.event.json
# for Role
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.role.requested < test/messages/taas.role.create.event.json
```

- Run `npm run view-data <model-name-here>` to see if documents were created.

## Update documents in ES
- Run the following commands to update `Job`, `JobCandidate`, `Interview`, `ResourceBooking`, `WorkPeriod`, `WorkPeriodPayment` documents in ES.
- Run the following commands to update `Job`, `JobCandidate`, `Interview`, `ResourceBooking`, `WorkPeriod`, `WorkPeriodPayment`, `Role` documents in ES.

``` bash
# for Job
Expand All @@ -37,12 +39,14 @@
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.workperiod.update < test/messages/taas.workperiod.update.event.json
# for WorkPeriodPayment
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.workperiodpayment.update < test/messages/taas.workperiodpayment.update.event.json
# for Role
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.role.update < test/messages/taas.role.update.event.json
```

- Run `npm run view-data <model-name-here>` to see if documents were updated.

## Delete documents in ES
- Run the following commands to delete `Job`, `JobCandidate`, `ResourceBooking`, `WorkPeriod` documents in ES.
- Run the following commands to delete `Job`, `JobCandidate`, `ResourceBooking`, `WorkPeriod`, `Role` documents in ES.

``` bash
# for Job
Expand All @@ -53,6 +57,8 @@
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.resourcebooking.delete < test/messages/taas.resourcebooking.delete.event.json
# for WorkPeriod
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.workperiod.delete < test/messages/taas.workperiod.delete.event.json
# for Role
docker exec -i taas-es-processor_kafka /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic taas.role.delete < test/messages/taas.role.delete.event.json
```

- Run `npm run view-data <model-name-here>` to see if documents were deleted.
9 changes: 7 additions & 2 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ module.exports = {
// topics for interview service
TAAS_INTERVIEW_REQUEST_TOPIC: process.env.TAAS_INTERVIEW_REQUEST_TOPIC || 'taas.interview.requested',
TAAS_INTERVIEW_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_UPDATE_TOPIC || 'taas.interview.update',
TAAS_INTERVIEW_BULK_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_BULK_UPDATE_TOPIC || 'taas.interview.bulkUpdate'
TAAS_INTERVIEW_BULK_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_BULK_UPDATE_TOPIC || 'taas.interview.bulkUpdate',
// topics for role service
TAAS_ROLE_CREATE_TOPIC: process.env.TAAS_ROLE_CREATE_TOPIC || 'taas.role.requested',
TAAS_ROLE_UPDATE_TOPIC: process.env.TAAS_ROLE_UPDATE_TOPIC || 'taas.role.update',
TAAS_ROLE_DELETE_TOPIC: process.env.TAAS_ROLE_DELETE_TOPIC || 'taas.role.delete'
},

esConfig: {
Expand All @@ -54,7 +58,8 @@ module.exports = {

ES_INDEX_JOB: process.env.ES_INDEX_JOB || 'job',
ES_INDEX_JOB_CANDIDATE: process.env.ES_INDEX_JOB_CANDIDATE || 'job_candidate',
ES_INDEX_RESOURCE_BOOKING: process.env.ES_INDEX_RESOURCE_BOOKING || 'resource_booking'
ES_INDEX_RESOURCE_BOOKING: process.env.ES_INDEX_RESOURCE_BOOKING || 'resource_booking',
ES_INDEX_ROLE: process.env.ES_INDEX_ROLE || 'role'
},

auth0: {
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@
"test/e2e/*.js"
]
}
}
}
7 changes: 6 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const ResourceBookingProcessorService = require('./services/ResourceBookingProce
const WorkPeriodProcessorService = require('./services/WorkPeriodProcessorService')
const InterviewProcessorService = require('./services/InterviewProcessorService')
const WorkPeriodPaymentProcessorService = require('./services/WorkPeriodPaymentProcessorService')
const RoleProcessorService = require('./services/RoleProcessorService')
const Mutex = require('async-mutex').Mutex
const events = require('events')

Expand Down Expand Up @@ -52,7 +53,11 @@ const topicServiceMapping = {
// interview
[config.topics.TAAS_INTERVIEW_REQUEST_TOPIC]: InterviewProcessorService.processRequestInterview,
[config.topics.TAAS_INTERVIEW_UPDATE_TOPIC]: InterviewProcessorService.processUpdateInterview,
[config.topics.TAAS_INTERVIEW_BULK_UPDATE_TOPIC]: InterviewProcessorService.processBulkUpdateInterviews
[config.topics.TAAS_INTERVIEW_BULK_UPDATE_TOPIC]: InterviewProcessorService.processBulkUpdateInterviews,
// role
[config.topics.TAAS_ROLE_CREATE_TOPIC]: RoleProcessorService.processCreate,
[config.topics.TAAS_ROLE_UPDATE_TOPIC]: RoleProcessorService.processUpdate,
[config.topics.TAAS_ROLE_DELETE_TOPIC]: RoleProcessorService.processDelete
}

// Start kafka consumer
Expand Down
5 changes: 3 additions & 2 deletions src/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ global.Promise = require('bluebird')
Joi.rateType = () => Joi.string().valid('hourly', 'daily', 'weekly', 'monthly')
Joi.jobStatus = () => Joi.string().valid('sourcing', 'in-review', 'assigned', 'closed', 'cancelled')
Joi.resourceBookingStatus = () => Joi.string().valid('placed', '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')
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')
Joi.workload = () => Joi.string().valid('full-time', 'fractional')
Joi.title = () => Joi.string().max(128)
Joi.paymentStatus = () => Joi.string().valid('pending', 'partially-completed', 'completed', 'cancelled')
Joi.xaiTemplate = () => Joi.string().valid(...allowedXAITemplates)
Joi.interviewStatus = () => Joi.string().valid(...allowedInterviewStatuses)
Joi.workPeriodPaymentStatus = () => Joi.string().valid('completed', 'cancelled')
Joi.workPeriodPaymentStatus = () => Joi.string().valid('completed', 'scheduled', 'in-progress', 'failed', 'cancelled')
// 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('')
Joi.smallint = () => Joi.number().min(-32768).max(32767)

const zapierSwitch = Joi.string().label('ZAPIER_SWITCH').valid(...Object.values(constants.Zapier.Switch))

Expand Down
79 changes: 77 additions & 2 deletions src/scripts/createIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ async function createIndex () {
rateType: { type: 'keyword' },
workload: { type: 'keyword' },
skills: { type: 'keyword' },
roles: { type: 'keyword' },
status: { type: 'keyword' },
isApplicationPageActive: { type: 'boolean' },
minSalary: { type: 'integer' },
maxSalary: { type: 'integer' },
hoursPerWeek: { type: 'integer' },
jobLocation: { type: 'keyword' },
jobTimezone: { type: 'keyword' },
currency: { type: 'keyword' },
roleIds: { type: 'keyword' },
createdAt: { type: 'date' },
createdBy: { type: 'keyword' },
updatedAt: { type: 'date' },
Expand All @@ -46,6 +54,7 @@ async function createIndex () {
status: { type: 'keyword' },
externalId: { type: 'keyword' },
resume: { type: 'text' },
remark: { type: 'keyword' },
interviews: {
type: 'nested',
properties: {
Expand Down Expand Up @@ -103,7 +112,8 @@ async function createIndex () {
properties: {
id: { type: 'keyword' },
resourceBookingId: { type: 'keyword' },
userHandle: { type: 'keyword' },
userHandle: { type: 'keyword',
normalizer: 'lowercaseNormalizer' },
projectId: { type: 'integer' },
userId: { type: 'keyword' },
startDate: { type: 'date', format: 'yyyy-MM-dd' },
Expand All @@ -120,6 +130,16 @@ async function createIndex () {
challengeId: { type: 'keyword' },
amount: { type: 'float' },
status: { type: 'keyword' },
statusDetails: {
type: 'nested',
properties: {
errorMessage: { type: 'text' },
errorCode: { type: 'integer' },
retry: { type: 'integer' },
step: { type: 'keyword' },
challengeId: { type: 'keyword' }
}
},
billingAccountId: { type: 'integer' },
createdAt: { type: 'date' },
createdBy: { type: 'keyword' },
Expand All @@ -140,11 +160,66 @@ async function createIndex () {
}
}
}
},
{ index: config.get('esConfig.ES_INDEX_ROLE'),
body: {
mappings: {
properties: {
name: { type: 'keyword' },
description: { type: 'keyword' },
listOfSkills: { type: 'keyword' },
rates: {
properties: {
global: { type: 'integer' },
inCountry: { type: 'integer' },
offShore: { type: 'integer' },
rate30Global: { type: 'integer' },
rate30InCountry: { type: 'integer' },
rate30OffShore: { type: 'integer' },
rate20Global: { type: 'integer' },
rate20InCountry: { type: 'integer' },
rate20OffShore: { type: 'integer' }
}
},
numberOfMembers: { type: 'integer' },
numberOfMembersAvailable: { type: 'integer' },
imageUrl: { type: 'keyword' },
timeToCandidate: { type: 'integer' },
timeToInterview: { type: 'integer' },
createdAt: { type: 'date' },
createdBy: { type: 'keyword' },
updatedAt: { type: 'date' },
updatedBy: { type: 'keyword' }
}
}
}
}
]

for (const index of indices) {
await esClient.indices.create(index)
await esClient.indices.create({ index: index.index })
await esClient.indices.close({ index: index.index })
await esClient.indices.putSettings({
index: index.index,
body: {
settings: {
analysis: {
normalizer: {
lowercaseNormalizer: {
filter: ['lowercase']
}
}
}
}
}
})
await esClient.indices.open({ index: index.index })
await esClient.indices.putMapping({
index: index.index,
body: {
properties: index.body.mappings.properties
}
})
logger.info({ component: 'createIndex', message: `ES Index ${index.index} creation succeeded!` })
}
process.exit(0)
Expand Down
3 changes: 2 additions & 1 deletion src/scripts/deleteIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ async function deleteIndex () {
const esClient = helper.getESClient()
const indices = [config.get('esConfig.ES_INDEX_JOB'),
config.get('esConfig.ES_INDEX_JOB_CANDIDATE'),
config.get('esConfig.ES_INDEX_RESOURCE_BOOKING')]
config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'),
config.get('esConfig.ES_INDEX_ROLE')]
for (const index of indices) {
await esClient.indices.delete({
index
Expand Down
3 changes: 2 additions & 1 deletion src/scripts/view-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const esClient = helper.getESClient()
const modelIndexMapping = {
Job: 'ES_INDEX_JOB',
JobCandidate: 'ES_INDEX_JOB_CANDIDATE',
ResourceBooking: 'ES_INDEX_RESOURCE_BOOKING'
ResourceBooking: 'ES_INDEX_RESOURCE_BOOKING',
Role: 'ES_INDEX_ROLE'
}

async function showESData () {
Expand Down
3 changes: 2 additions & 1 deletion src/services/JobCandidateProcessorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ 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),
remark: Joi.string().allow(null)
}).required()
}).required(),
transactionId: Joi.string().required()
Expand Down
10 changes: 9 additions & 1 deletion src/services/JobProcessorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,20 @@ processCreate.schema = {
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()
isApplicationPageActive: Joi.boolean().required(),
minSalary: Joi.number().integer().allow(null),
maxSalary: Joi.number().integer().allow(null),
hoursPerWeek: Joi.number().integer().allow(null),
jobLocation: Joi.string().allow(null),
jobTimezone: Joi.string().allow(null),
currency: Joi.string().allow(null),
roleIds: Joi.array().items(Joi.string().uuid().required()).allow(null)
}).required()
}).required(),
transactionId: Joi.string().required()
Expand Down
Loading