Skip to content

Feature/interview scheduler2 #226

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
merged 7 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
AUTH0_AUDIENCE_UBAHN=
AUTH0_CLIENT_ID=
AUTH0_CLIENT_SECRET=

# necessary if you'll utilize email functionality of interviews
INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID=
INTERVIEW_INVITATION_SENDER_EMAIL=
# Locally deployed services (via docker-compose)
ES_HOST=dockerhost:9200
DATABASE_URL=postgres://postgres:postgres@dockerhost:5432/postgres
Expand Down
25 changes: 24 additions & 1 deletion app-constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,29 @@ const Scopes = {
READ_WORK_PERIOD_PAYMENT: 'read:taas-workPeriodPayments',
CREATE_WORK_PERIOD_PAYMENT: 'create:taas-workPeriodPayments',
UPDATE_WORK_PERIOD_PAYMENT: 'update:taas-workPeriodPayments',
ALL_WORK_PERIOD_PAYMENT: 'all:taas-workPeriodPayments'
ALL_WORK_PERIOD_PAYMENT: 'all:taas-workPeriodPayments',
// interview
READ_INTERVIEW: 'read:taas-interviews',
CREATE_INTERVIEW: 'create:taas-interviews',
UPDATE_INTERVIEW: 'update:taas-interviews',
ALL_INTERVIEW: 'all:taas-interviews'
}

// Interview related constants
const Interviews = {
Status: {
Scheduling: 'Scheduling',
Scheduled: 'Scheduled',
RequestedForReschedule: 'Requested for reschedule',
Rescheduled: 'Rescheduled',
Completed: 'Completed',
Cancelled: 'Cancelled'
},
// key: template name in x.ai, value: duration
XaiTemplate: {
'30-minutes': 30,
'60-minutes': 60
}
}

const ChallengeStatus = {
Expand All @@ -62,6 +84,7 @@ module.exports = {
UserRoles,
FullManagePermissionRoles,
Scopes,
Interviews,
ChallengeStatus,
PaymentProcessingSwitch
}
4 changes: 4 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ const express = require('express')
const cors = require('cors')
const HttpStatus = require('http-status-codes')
const interceptor = require('express-interceptor')
const schedule = require('node-schedule')
const logger = require('./src/common/logger')
const eventHandlers = require('./src/eventHandlers')
const interviewService = require('./src/services/InterviewService')

// setup express app
const app = express()
Expand Down Expand Up @@ -93,6 +95,8 @@ app.use((err, req, res, next) => {
const server = app.listen(app.get('port'), () => {
logger.info({ component: 'app', message: `Express server listening on port ${app.get('port')}` })
eventHandlers.init()
// schedule updateCompletedInterviews to run every hour
schedule.scheduleJob('0 0 * * * *', interviewService.updateCompletedInterviews)
})

if (process.env.NODE_ENV === 'test') {
Expand Down
15 changes: 15 additions & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ module.exports = {
TAAS_WORK_PERIOD_PAYMENT_UPDATE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_UPDATE_TOPIC || 'taas.workperiodpayment.update',
// the delete work period payment entity Kafka message topic
TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC: process.env.TAAS_WORK_PERIOD_PAYMENT_DELETE_TOPIC || 'taas.workperiodpayment.delete',
// topics for interview service
// the request interview Kafka message topic
TAAS_INTERVIEW_REQUEST_TOPIC: process.env.TAAS_INTERVIEW_REQUEST_TOPIC || 'taas.interview.requested',
// the interview update Kafka message topic
TAAS_INTERVIEW_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_UPDATE_TOPIC || 'taas.interview.update',
// the interview bulk update Kafka message topic
TAAS_INTERVIEW_BULK_UPDATE_TOPIC: process.env.TAAS_INTERVIEW_BULK_UPDATE_TOPIC || 'taas.interview.bulkUpdate',

// the Kafka message topic for sending email
EMAIL_TOPIC: process.env.EMAIL_TOPIC || 'external.action.email',
Expand All @@ -135,10 +142,18 @@ module.exports = {
// the emails address for receiving the issue report
// REPORT_ISSUE_EMAILS may contain comma-separated list of email which is converted to array
REQUEST_EXTENSION_EMAILS: (process.env.REQUEST_EXTENSION_EMAILS || '').split(','),
// the emails address for interview invitation
// INTERVIEW_INVITATION_CC_LIST may contain comma-separated list of email which is converted to array
// scheduler@x.ai should be in the CC list
INTERVIEW_INVITATION_CC_LIST: (process.env.INTERVIEW_INVITATION_CC_LIST || 'scheduler@x.ai').split(','),
// SendGrid email template ID for reporting issue
REPORT_ISSUE_SENDGRID_TEMPLATE_ID: process.env.REPORT_ISSUE_SENDGRID_TEMPLATE_ID,
// SendGrid email template ID for requesting extension
REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID: process.env.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID,
// SendGrid email template ID for interview invitation
INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID: process.env.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID,
// The sender (aka `from`) email for invitation.
INTERVIEW_INVITATION_SENDER_EMAIL: process.env.INTERVIEW_INVITATION_SENDER_EMAIL || 'scheduler@topcoder.com',
// the URL where TaaS App is hosted
TAAS_APP_URL: process.env.TAAS_APP_URL || 'https://platform.topcoder-dev.com/taas/myteams',
// environment variables for Payment Service
Expand Down
38 changes: 38 additions & 0 deletions config/email_template.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,43 @@ module.exports = {
'{{text}}',
recipients: config.REPORT_ISSUE_EMAILS,
sendgridTemplateId: config.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID
},

/* Request interview for a job candidate
*
* - interviewType: the x.ai interview type. Example: "30-minutes"
* - interviewRound: the round of the interview. Example: 2
* - interviewDuration: duration of the interview, in minutes. Example: 30
* - interviewerList: The list of interviewer email addresses. Example: "first@attendee.com, second@attendee.com"
* - candidateId: the id of the jobCandidate. Example: "cc562545-7b75-48bf-87e7-50b3c57e41b1"
* - candidateName: Full name of candidate. Example: "John Doe"
* - jobName: The title of the job. Example: "TaaS API Misc Updates"
*
* Template (defined in SendGrid):
* Subject: '{{interviewType}} tech interview with {{candidateName}} for {{jobName}} is requested by the Customer'
* Body:
* 'Hello!
* <br /><br />
* Congratulations, you have been selected to participate in a Topcoder Gig Work Interview!
* <br /><br />
* Please monitor your email for a response to this where you can coordinate your availability.
* <br /><br />
* Interviewee: {{candidateName}}<br />
* Interviewer(s): {{interviewerList}}<br />
* Interview Length: {{interviewDuration}} minutes
* <br /><br />
* /{{interviewType}}
* <br /><br />
* Topcoder Info:<br />
* Note: "id: {{candidateId}}, round: {{interviewRound}}"'
*
* Note, that the template should be defined in SendGrid.
* The subject & body above (identical to actual SendGrid template) is for reference purposes.
* We won't pass subject & body but only substitutions (replacements in template subject/body).
*/
'interview-invitation': {
from: config.INTERVIEW_INVITATION_SENDER_EMAIL,
cc: config.INTERVIEW_INVITATION_CC_LIST,
sendgridTemplateId: config.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID
}
}
2,387 changes: 2,386 additions & 1 deletion data/demo-data.json

Large diffs are not rendered by default.

Loading