Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit bc4d324

Browse files
committed
feat: add phase criteria for submission, reivew and registration phase
Signed-off-by: Rakib Ansary <[email protected]>
1 parent 61eea6d commit bc4d324

File tree

3 files changed

+157
-1
lines changed

3 files changed

+157
-1
lines changed

.circleci/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ workflows:
7272
branches:
7373
only:
7474
- develop
75-
- PLAT-2035
75+
- PLAT-2032
7676

7777
# Production builds are exectuted only on tagged commits to the
7878
# master branch.

src/services/ProcessorService.js

+75
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const { createOrSetNumberOfReviewers } = require('./selfServiceReviewerService')
2020
const { disableTimelineNotifications } = require('./selfServiceNotificationService')
2121
const legacyChallengeService = require('./legacyChallengeService')
2222
const legacyChallengeReviewService = require('./legacyChallengeReviewService')
23+
const phaseCriteriaService = require('./phaseCriteriaService');
2324

2425
/**
2526
* Drop and recreate phases in ifx
@@ -92,6 +93,79 @@ async function recreatePhases (legacyId, v5Phases, createdBy) {
9293
logger.info('recreatePhases :: end')
9394
}
9495

96+
async function addPhaseConstraints(legacyId, v5Phases, createdBy) {
97+
logger.info(`addPhaseConstraints :: start: ${legacyId}, ${JSON.stringify(v5Phases)}`)
98+
const allPhaseCriteria = await phaseCriteriaService.getPhaseCriteria();
99+
logger.info(`addPhaseConstraints :: allPhaseCriteria: ${JSON.stringify(allPhaseCriteria)}`)
100+
101+
const phaseTypes = await timelineService.getPhaseTypes()
102+
logger.info(`addPhaseConstraints :: phaseTypes: ${JSON.stringify(phaseTypes)}`)
103+
104+
const phasesFromIFx = await timelineService.getChallengePhases(legacyId)
105+
106+
for (const phase of v5Phases) {
107+
logger.info(`addPhaseConstraints :: phase: ${legacyId} -> ${JSON.stringify(phase)}`)
108+
if (phase.constraints == null || phase.constraints.length === 0) continue;
109+
110+
const phaseLegacyId = _.get(_.find(phaseTypes, pt => pt.name === phase.name), 'phase_type_id')
111+
const existingLegacyPhase = _.find(phasesFromIFx, p => p.phase_type_id === phaseLegacyId)
112+
113+
const projectPhaseId = _.get(existingLegacyPhase, 'project_phase_id')
114+
if (!projectPhaseId) {
115+
logger.warn(`Could not find phase ${phase.name} on legacy!`)
116+
continue
117+
}
118+
119+
let constraintName = null;
120+
let constraintValue = null
121+
122+
if (phase.name === 'Submission') {
123+
const numSubmissionsConstraint = phase.constraints.find(c => c.name === 'Number of Submissions')
124+
if (numSubmissionsConstraint) {
125+
constraintName = 'Submission Number'
126+
constraintValue = numSubmissionsConstraint.value
127+
}
128+
}
129+
130+
if (phase.name === 'Registration') {
131+
const numRegistrantsConstraint = phase.constraints.find(c => c.name === 'Number of Registrants')
132+
if (numRegistrantsConstraint) {
133+
constraintName = 'Registration Number'
134+
constraintValue = numRegistrantsConstraint.value
135+
}
136+
}
137+
138+
if (phase.name === 'Review') {
139+
const numReviewersConstraint = phase.constraints.find(c => c.name === 'Number of Reviewers')
140+
if (numReviewersConstraint) {
141+
constraintName = 'Reviewer Number'
142+
constraintValue = numReviewersConstraint.value
143+
}
144+
}
145+
146+
// We have an interesting situation if a submission phase constraint was added but
147+
// no registgration phase constraint was added. This ends up opening Post-Mortem
148+
// phase if registration closes with 0 submissions.
149+
// For now I'll leave it as is and handle this better in the new Autopilot implementation
150+
// A quick solution would have been adding a registration constraint with value 1 if none is provided when there is a submission phase constraint
151+
152+
if (constraintName && constraintValue) {
153+
const phaseCriteriaTypeId = _.get(_.find(allPhaseCriteria, pc => pc.name === constraintName), 'phase_criteria_type_id')
154+
if (phaseCriteriaTypeId) {
155+
logger.debug(`Will create phase constraint ${constraintName} with value ${constraintValue}`)
156+
// Ideally we should update the existing phase criteria, but this processor will go away in weeks
157+
// and it's a backend processor, so we can just drop and recreate without slowing down anything
158+
await phaseCriteriaService.dropPhaseCriteria(projectPhaseId, phaseCriteriaTypeId)
159+
await phaseCriteriaService.createPhaseCriteria(projectPhaseId, phaseCriteriaTypeId, constraintValue, createdBy)
160+
} else {
161+
logger.warn(`Could not find phase criteria type for ${constraintName}`)
162+
}
163+
}
164+
165+
}
166+
logger.info('addPhaseConstraints :: end')
167+
}
168+
95169
/**
96170
* Sync the information from the v5 phases into legacy
97171
* @param {Number} legacyId the legacy challenge ID
@@ -806,6 +880,7 @@ async function processMessage (message) {
806880
if (!_.get(message.payload, 'task.isTask')) {
807881
const numOfReviewers = 2
808882
await syncChallengePhases(legacyId, message.payload.phases, createdByUserId, _.get(message, 'payload.legacy.selfService'), numOfReviewers, isBeingActivated)
883+
await addPhaseConstraints(legacyId, message.payload.phases, createdByUserId);
809884
needSyncV4ES = true
810885
} else {
811886
logger.info('Will skip syncing phases as the challenge is a task...')

src/services/phaseCriteriaService.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* Number of reviewers Service
3+
* Interacts with InformixDB
4+
*/
5+
const util = require('util')
6+
const logger = require('../common/logger')
7+
const helper = require('../common/helper')
8+
9+
const QUERY_GET_PHASE_CRITERIA = 'SELECT phase_criteria_type_id, name FROM phase_criteria_type_lu;'
10+
const QUERY_CREATE = 'INSERT INTO phase_criteria (project_phase_id, phase_criteria_type_id, parameter, create_user, create_date, modify_user, modify_date) VALUES (?, ?, ?, ?, CURRENT, ?, CURRENT)'
11+
const QUERY_DELETE = 'DELETE FROM phase_criteria WHERE project_phase_id = ? AND phase_criteria_type_id = ?'
12+
13+
/**
14+
* Prepare Informix statement
15+
* @param {Object} connection the Informix connection
16+
* @param {String} sql the sql
17+
* @return {Object} Informix statement
18+
*/
19+
async function prepare (connection, sql) {
20+
// logger.debug(`Preparing SQL ${sql}`)
21+
const stmt = await connection.prepareAsync(sql)
22+
return Promise.promisifyAll(stmt)
23+
}
24+
25+
async function getPhaseCriteria () {
26+
const connection = await helper.getInformixConnection()
27+
let result = null
28+
try {
29+
result = await connection.queryAsync(QUERY_GET_PHASE_CRITERIA)
30+
} catch (e) {
31+
logger.error(`Error in 'getPhaseCriteria' ${e}`)
32+
throw e
33+
} finally {
34+
await connection.closeAsync()
35+
}
36+
return result
37+
}
38+
39+
async function dropPhaseCriteria(phaseId, phaseCriteriaTypeId) {
40+
const connection = await helper.getInformixConnection()
41+
let result = null
42+
try {
43+
await connection.beginTransactionAsync()
44+
const query = await prepare(connection, QUERY_DELETE)
45+
result = await query.executeAsync([phaseId, phaseCriteriaTypeId])
46+
await connection.commitTransactionAsync()
47+
} catch (e) {
48+
logger.error(`Error in 'dropPhaseCriteria' ${e}`)
49+
await connection.rollbackTransactionAsync()
50+
throw e
51+
} finally {
52+
await connection.closeAsync()
53+
}
54+
return result
55+
}
56+
57+
async function createPhaseCriteria(phaseId, phaseCriteriaTypeId, value, createdBy) {
58+
const connection = await helper.getInformixConnection()
59+
let result = null
60+
try {
61+
await connection.beginTransactionAsync()
62+
const query = await prepare(connection, QUERY_CREATE)
63+
result = await query.executeAsync([phaseId, phaseCriteriaTypeId, value, createdBy, createdBy])
64+
await connection.commitTransactionAsync()
65+
} catch (e) {
66+
logger.error(`Error in 'createPhaseCriteria' ${e}`)
67+
await connection.rollbackTransactionAsync()
68+
throw e
69+
} finally {
70+
await connection.closeAsync()
71+
}
72+
return result
73+
}
74+
75+
76+
77+
module.exports = {
78+
getPhaseCriteria,
79+
createPhaseCriteria,
80+
dropPhaseCriteria
81+
}

0 commit comments

Comments
 (0)