Skip to content

Commit ccf7136

Browse files
committed
Merge branch 'feature/timeline-milestone' into issue/127
2 parents 0a504f4 + 2bcc524 commit ccf7136

File tree

20 files changed

+692
-64
lines changed

20 files changed

+692
-64
lines changed

config/development.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"pubsubQueueName": "dev.project.service",
33
"pubsubExchangeName": "dev.projects",
4-
"attachmentsS3Bucket": "topcoder-dev-media"
4+
"attachmentsS3Bucket": "topcoder-dev-media",
5+
"connectProjectsUrl": "https://connect.topcoder-dev.com/projects/"
56
}

config/production.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"authDomain": "topcoder.com"
2+
"authDomain": "topcoder.com",
3+
"connectProjectsUrl": "https://connect.topcoder.com/projects/",
34
}

config/test.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"timelineDocType": "timelineV4"
1313
},
1414
"rabbitmqUrl": "amqp://localhost:5672",
15+
"connectProjectsUrl": "https://local.topcoder-dev.com/projects/",
1516
"dbConfig": {
1617
"masterUrl": "postgres://coder:mysecretpassword@localhost:5432/projectsdb_test",
1718
"maxPoolSize": 50,

migrations/20180727_product_categories.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ ALTER TABLE ONLY product_categories
3232
--
3333
ALTER TABLE product_templates ADD COLUMN "category" character varying(45);
3434
UPDATE product_templates set category='generic' where category is null;
35-
ALTER TABLE product_templates ALTER COLUMN "generic" SET NOT NULL;
35+
ALTER TABLE product_templates ALTER COLUMN "category" SET NOT NULL;

postman.json

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4062,6 +4062,108 @@
40624062
},
40634063
"response": []
40644064
},
4065+
{
4066+
"name": "Clone milestone template",
4067+
"request": {
4068+
"method": "POST",
4069+
"header": [
4070+
{
4071+
"key": "Content-Type",
4072+
"value": "application/json"
4073+
},
4074+
{
4075+
"key": "Authorization",
4076+
"value": "Bearer {{jwt-token-admin-40051333}}"
4077+
}
4078+
],
4079+
"body": {
4080+
"mode": "raw",
4081+
"raw": "{\r\n \"param\":{\r\n \"sourceTemplateId\": 1\r\n }\r\n}"
4082+
},
4083+
"url": {
4084+
"raw": "{{api-url}}/v4/productTemplates/2/milestones/clone",
4085+
"host": [
4086+
"{{api-url}}"
4087+
],
4088+
"path": [
4089+
"v4",
4090+
"productTemplates",
4091+
"2",
4092+
"milestones",
4093+
"clone"
4094+
]
4095+
}
4096+
},
4097+
"response": []
4098+
},
4099+
{
4100+
"name": "Clone milestone template with invalid product template id",
4101+
"request": {
4102+
"method": "POST",
4103+
"header": [
4104+
{
4105+
"key": "Content-Type",
4106+
"value": "application/json"
4107+
},
4108+
{
4109+
"key": "Authorization",
4110+
"value": "Bearer {{jwt-token-admin-40051333}}"
4111+
}
4112+
],
4113+
"body": {
4114+
"mode": "raw",
4115+
"raw": "{\r\n \"param\":{\r\n \"sourceTemplateId\": 1\r\n }\r\n}"
4116+
},
4117+
"url": {
4118+
"raw": "{{api-url}}/v4/productTemplates/5/milestones/clone",
4119+
"host": [
4120+
"{{api-url}}"
4121+
],
4122+
"path": [
4123+
"v4",
4124+
"productTemplates",
4125+
"5",
4126+
"milestones",
4127+
"clone"
4128+
]
4129+
}
4130+
},
4131+
"response": []
4132+
},
4133+
{
4134+
"name": "Clone milestone template with invalid source product template id",
4135+
"request": {
4136+
"method": "POST",
4137+
"header": [
4138+
{
4139+
"key": "Content-Type",
4140+
"value": "application/json"
4141+
},
4142+
{
4143+
"key": "Authorization",
4144+
"value": "Bearer {{jwt-token-admin-40051333}}"
4145+
}
4146+
],
4147+
"body": {
4148+
"mode": "raw",
4149+
"raw": "{\r\n \"param\":{\r\n \"sourceTemplateId\": 6\r\n }\r\n}"
4150+
},
4151+
"url": {
4152+
"raw": "{{api-url}}/v4/productTemplates/2/milestones/clone",
4153+
"host": [
4154+
"{{api-url}}"
4155+
],
4156+
"path": [
4157+
"v4",
4158+
"productTemplates",
4159+
"2",
4160+
"milestones",
4161+
"clone"
4162+
]
4163+
}
4164+
},
4165+
"response": []
4166+
},
40654167
{
40664168
"name": "List milestone templates",
40674169
"request": {

src/events/busApi.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import _ from 'lodash';
2-
import 'config';
2+
import config from 'config';
33
import { EVENT, BUS_API_EVENT, PROJECT_STATUS, PROJECT_MEMBER_ROLE } from '../constants';
44
import { createEvent } from '../services/busApi';
55
import models from '../models';
@@ -17,6 +17,27 @@ const mapEventTypes = {
1717
[PROJECT_STATUS.ACTIVE]: BUS_API_EVENT.PROJECT_ACTIVE,
1818
};
1919

20+
/**
21+
* Builds the connect project attachment url for the given project and attachment ids.
22+
*
23+
* @param {string|number} projectId the project id
24+
* @param {string|number} attachmentId the attachment id
25+
* @returns {string} the connect project attachment url
26+
*/
27+
function connectProjectAttachmentUrl(projectId, attachmentId) {
28+
return `${config.get('connectProjectsUrl')}${projectId}/attachments/${attachmentId}`;
29+
}
30+
31+
/**
32+
* Builds the connect project url for the given project id.
33+
*
34+
* @param {string|number} projectId the project id
35+
* @returns {string} the connect project url
36+
*/
37+
function connectProjectUrl(projectId) {
38+
return `${config.get('connectProjectsUrl')}${projectId}`;
39+
}
40+
2041
module.exports = (app, logger) => {
2142
/**
2243
* PROJECT_DRAFT_CREATED
@@ -28,6 +49,7 @@ module.exports = (app, logger) => {
2849
createEvent(BUS_API_EVENT.PROJECT_CREATED, {
2950
projectId: project.id,
3051
projectName: project.name,
52+
projectUrl: connectProjectUrl(project.id),
3153
userId: req.authUser.userId,
3254
initiatorUserId: req.authUser.userId,
3355
}, logger);
@@ -44,6 +66,7 @@ module.exports = (app, logger) => {
4466
createEvent(mapEventTypes[updated.status], {
4567
projectId: updated.id,
4668
projectName: updated.name,
69+
projectUrl: connectProjectUrl(updated.id),
4770
userId: req.authUser.userId,
4871
initiatorUserId: req.authUser.userId,
4972
}, logger);
@@ -55,6 +78,7 @@ module.exports = (app, logger) => {
5578
createEvent(BUS_API_EVENT.PROJECT_SPECIFICATION_MODIFIED, {
5679
projectId: updated.id,
5780
projectName: updated.name,
81+
projectUrl: connectProjectUrl(updated.id),
5882
userId: req.authUser.userId,
5983
initiatorUserId: req.authUser.userId,
6084
}, logger);
@@ -63,6 +87,7 @@ module.exports = (app, logger) => {
6387
createEvent(BUS_API_EVENT.PROJECT_LINK_CREATED, {
6488
projectId: updated.id,
6589
projectName: updated.name,
90+
projectUrl: connectProjectUrl(updated.id),
6691
userId: req.authUser.userId,
6792
initiatorUserId: req.authUser.userId,
6893
}, logger);
@@ -96,6 +121,7 @@ module.exports = (app, logger) => {
96121
createEvent(eventType, {
97122
projectId,
98123
projectName: project.name,
124+
projectUrl: connectProjectUrl(projectId),
99125
userId: member.userId,
100126
initiatorUserId: req.authUser.userId,
101127
}, logger);
@@ -124,6 +150,7 @@ module.exports = (app, logger) => {
124150
createEvent(eventType, {
125151
projectId,
126152
projectName: project.name,
153+
projectUrl: connectProjectUrl(projectId),
127154
userId: member.userId,
128155
initiatorUserId: req.authUser.userId,
129156
}, logger);
@@ -147,6 +174,7 @@ module.exports = (app, logger) => {
147174
createEvent(BUS_API_EVENT.MEMBER_ASSIGNED_AS_OWNER, {
148175
projectId,
149176
projectName: project.name,
177+
projectUrl: connectProjectUrl(projectId),
150178
userId: updated.userId,
151179
initiatorUserId: req.authUser.userId,
152180
}, logger);
@@ -170,7 +198,9 @@ module.exports = (app, logger) => {
170198
createEvent(BUS_API_EVENT.PROJECT_FILE_UPLOADED, {
171199
projectId,
172200
projectName: project.name,
201+
projectUrl: connectProjectUrl(projectId),
173202
fileName: attachment.filePath.replace(/^.*[\\\/]/, ''), // eslint-disable-line
203+
fileUrl: connectProjectAttachmentUrl(projectId, attachment.id),
174204
userId: req.authUser.userId,
175205
initiatorUserId: req.authUser.userId,
176206
}, logger);
@@ -192,6 +222,7 @@ module.exports = (app, logger) => {
192222
createEvent(BUS_API_EVENT.PROJECT_PLAN_MODIFIED, {
193223
projectId,
194224
projectName: project.name,
225+
projectUrl: connectProjectUrl(projectId),
195226
userId: req.authUser.userId,
196227
initiatorUserId: req.authUser.userId,
197228
}, logger);
@@ -213,6 +244,7 @@ module.exports = (app, logger) => {
213244
createEvent(BUS_API_EVENT.PROJECT_PLAN_MODIFIED, {
214245
projectId,
215246
projectName: project.name,
247+
projectUrl: connectProjectUrl(projectId),
216248
userId: req.authUser.userId,
217249
initiatorUserId: req.authUser.userId,
218250
}, logger);
@@ -234,6 +266,7 @@ module.exports = (app, logger) => {
234266
createEvent(BUS_API_EVENT.PROJECT_PLAN_MODIFIED, {
235267
projectId,
236268
projectName: project.name,
269+
projectUrl: connectProjectUrl(projectId),
237270
userId: req.authUser.userId,
238271
initiatorUserId: req.authUser.userId,
239272
}, logger);
@@ -255,6 +288,7 @@ module.exports = (app, logger) => {
255288
createEvent(BUS_API_EVENT.PROJECT_PLAN_MODIFIED, {
256289
projectId,
257290
projectName: project.name,
291+
projectUrl: connectProjectUrl(projectId),
258292
userId: req.authUser.userId,
259293
initiatorUserId: req.authUser.userId,
260294
phase: created,
@@ -277,6 +311,7 @@ module.exports = (app, logger) => {
277311
createEvent(BUS_API_EVENT.PROJECT_PLAN_MODIFIED, {
278312
projectId,
279313
projectName: project.name,
314+
projectUrl: connectProjectUrl(projectId),
280315
userId: req.authUser.userId,
281316
initiatorUserId: req.authUser.userId,
282317
}, logger);
@@ -302,6 +337,7 @@ module.exports = (app, logger) => {
302337
createEvent(BUS_API_EVENT.PROJECT_PRODUCT_SPECIFICATION_MODIFIED, {
303338
projectId,
304339
projectName: project.name,
340+
projectUrl: connectProjectUrl(projectId),
305341
userId: req.authUser.userId,
306342
initiatorUserId: req.authUser.userId,
307343
}, logger);
@@ -314,6 +350,7 @@ module.exports = (app, logger) => {
314350
createEvent(BUS_API_EVENT.PROJECT_PLAN_MODIFIED, {
315351
projectId,
316352
projectName: project.name,
353+
projectUrl: connectProjectUrl(projectId),
317354
userId: req.authUser.userId,
318355
initiatorUserId: req.authUser.userId,
319356
}, logger);

src/permissions/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module.exports = () => {
4343
Authorizer.setPolicy('project.updatePhaseProduct', copilotAndAbove);
4444
Authorizer.setPolicy('project.deletePhaseProduct', copilotAndAbove);
4545

46+
Authorizer.setPolicy('milestoneTemplate.clone', projectAdmin);
4647
Authorizer.setPolicy('milestoneTemplate.create', projectAdmin);
4748
Authorizer.setPolicy('milestoneTemplate.edit', projectAdmin);
4849
Authorizer.setPolicy('milestoneTemplate.delete', projectAdmin);

src/routes/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ router.route('/v4/productTemplates/:productTemplateId(\\d+)/milestones')
108108
.post(require('./milestoneTemplates/create'))
109109
.get(require('./milestoneTemplates/list'));
110110

111+
router.route('/v4/productTemplates/:productTemplateId(\\d+)/milestones/clone')
112+
.post(require('./milestoneTemplates/clone'));
113+
111114
router.route('/v4/productTemplates/:productTemplateId(\\d+)/milestones/:milestoneTemplateId(\\d+)')
112115
.get(require('./milestoneTemplates/get'))
113116
.patch(require('./milestoneTemplates/update'))

0 commit comments

Comments
 (0)