Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 12b9c95

Browse files
authoredDec 29, 2020
Merge pull request #605 from topcoder-platform/develop
Minor release - 3.2.0
2 parents 236e581 + 7269344 commit 12b9c95

File tree

19 files changed

+402
-199
lines changed

19 files changed

+402
-199
lines changed
 

‎README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,26 @@ Local setup should work good on **Linux**, **macOS** and **Windows**.
174174
Runs the Project Service using nodemon, so it would be restarted after any of the files is updated.
175175
The project service will be served on `http://localhost:8001`.
176176
177-
4. *(Optional)* Start Project Service Kafka Consumer
178-
179-
*Run this only if you want to test or modify logic of `lastActivityAt` or `lastActivityBy`.*
177+
4. Start Project Service Kafka Consumer
180178
181179
In another terminal window run:
182180
183181
```bash
184182
npm run startKafkaConsumers:dev
185183
```
186184
185+
<details><summary>Click to learn what this service does</summary>
186+
<br>
187+
188+
This service run Kafka Consumer which listens to some events and handles the next things:
189+
- updates `lastActivityAt` and `lastActivityUserId` for projects when we make any updates related to the project like updating project, project attachments, project plan, project members create/delete topics and so on
190+
- create/update/delete topics for phases when we create/update/delete phases
191+
- update phase progress and duration when milestone is completed
192+
- see all the Kafka handlers in file [src/events/kafkaHandlers.js](./src/events/kafkaHandlers.js)
193+
194+
</details>
195+
196+
187197
## Run Connect App with Project Service locally
188198
189199
To be able to run [Connect App](https://github.com/appirio-tech/connect-app) with the local setup of Project Service we have to do two things:

‎config/default.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,6 @@
7575
"EMBED_REPORTS_MAPPING": "{\"mock\": \"/embed/looks/2\"}",
7676
"ALLOWED_USERS": "[]"
7777
},
78-
"DEFAULT_M2M_USERID": -101
78+
"DEFAULT_M2M_USERID": -101,
79+
"taasJobApiUrl": "https://api.topcoder.com/v5/jobs"
7980
}

‎config/development.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"fileServiceEndpoint": "https://api.topcoder-dev.com/v3/files/",
77
"connectProjectsUrl": "https://connect.topcoder-dev.com/projects/",
88
"memberServiceEndpoint": "https://api.topcoder-dev.com/v3/members",
9-
"identityServiceEndpoint": "https://api.topcoder-dev.com/v3/"
9+
"identityServiceEndpoint": "https://api.topcoder-dev.com/v3/",
10+
"taasJobApiUrl": "https://api.topcoder-dev.com/v5/jobs"
1011
}

‎docs/permissions.html

Lines changed: 88 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,37 @@ <h2 class="anchor-container">
259259
</div>
260260
</div>
261261
</div>
262+
<div class="row border-top">
263+
<div class="col py-2">
264+
<div class="permission-title anchor-container">
265+
<a href="#UPDATE_PROJECT_STATUS" name="UPDATE_PROJECT_STATUS" class="anchor"></a>Update Project Status
266+
</div>
267+
<div class="permission-variable"><small><code>UPDATE_PROJECT_STATUS</code></small></div>
268+
<div class="text-black-50 small-text"></div>
269+
</div>
270+
<div class="col-9 py-2">
271+
<div>
272+
<span class="badge badge-primary" title="Allowed Project Role">manager</span>
273+
<span class="badge badge-primary" title="Allowed Project Role">account_manager</span>
274+
<span class="badge badge-primary" title="Allowed Project Role">program_manager</span>
275+
<span class="badge badge-primary" title="Allowed Project Role">account_executive</span>
276+
<span class="badge badge-primary" title="Allowed Project Role">solution_architect</span>
277+
<span class="badge badge-primary" title="Allowed Project Role">project_manager</span>
278+
<span class="badge badge-primary" title="Allowed Project Role">copilot</span>
279+
</div>
280+
281+
<div>
282+
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
283+
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
284+
</div>
285+
286+
<div>
287+
<span class="badge badge-dark" title="Allowed Topcoder Role">all:connect_project</span>
288+
<span class="badge badge-dark" title="Allowed Topcoder Role">all:projects</span>
289+
<span class="badge badge-dark" title="Allowed Topcoder Role">write:projects</span>
290+
</div>
291+
</div>
292+
</div>
262293
<div class="row border-top">
263294
<div class="col py-2">
264295
<div class="permission-title anchor-container">
@@ -523,19 +554,19 @@ <h2 class="anchor-container">
523554
<div class="row border-top">
524555
<div class="col py-2">
525556
<div class="permission-title anchor-container">
526-
<a href="#UPDATE_PROJECT_MEMBER_TO_COPILOT" name="UPDATE_PROJECT_MEMBER_TO_COPILOT" class="anchor"></a>Update Project Member (to copilot)
557+
<a href="#DELETE_PROJECT_MEMBER_CUSTOMER" name="DELETE_PROJECT_MEMBER_CUSTOMER" class="anchor"></a>Delete Project Member (customer)
527558
</div>
528-
<div class="permission-variable"><small><code>UPDATE_PROJECT_MEMBER_TO_COPILOT</code></small></div>
529-
<div class="text-black-50 small-text">Who can update project member role to &quot;copilot&quot;.</div>
559+
<div class="permission-variable"><small><code>DELETE_PROJECT_MEMBER_CUSTOMER</code></small></div>
560+
<div class="text-black-50 small-text">Who can delete project members with &quot;customer&quot; role.</div>
530561
</div>
531562
<div class="col-9 py-2">
532563
<div>
564+
<span class="badge badge-primary" title="Allowed">Any Project Member</span>
533565
</div>
534566

535567
<div>
536568
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
537569
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
538-
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Copilot Manager</span>
539570
</div>
540571

541572
<div>
@@ -548,14 +579,19 @@ <h2 class="anchor-container">
548579
<div class="row border-top">
549580
<div class="col py-2">
550581
<div class="permission-title anchor-container">
551-
<a href="#DELETE_PROJECT_MEMBER_CUSTOMER" name="DELETE_PROJECT_MEMBER_CUSTOMER" class="anchor"></a>Delete Project Member (customer)
582+
<a href="#DELETE_PROJECT_MEMBER_TOPCODER" name="DELETE_PROJECT_MEMBER_TOPCODER" class="anchor"></a>Delete Project Member (topcoder)
552583
</div>
553-
<div class="permission-variable"><small><code>DELETE_PROJECT_MEMBER_CUSTOMER</code></small></div>
554-
<div class="text-black-50 small-text">Who can delete project members with &quot;customer&quot; role.</div>
584+
<div class="permission-variable"><small><code>DELETE_PROJECT_MEMBER_TOPCODER</code></small></div>
585+
<div class="text-black-50 small-text">Who can delete project members with some topcoder role like &quot;manager&quot; etc.</div>
555586
</div>
556587
<div class="col-9 py-2">
557588
<div>
558-
<span class="badge badge-primary" title="Allowed">Any Project Member</span>
589+
<span class="badge badge-primary" title="Allowed Project Role">manager</span>
590+
<span class="badge badge-primary" title="Allowed Project Role">account_manager</span>
591+
<span class="badge badge-primary" title="Allowed Project Role">program_manager</span>
592+
<span class="badge badge-primary" title="Allowed Project Role">account_executive</span>
593+
<span class="badge badge-primary" title="Allowed Project Role">solution_architect</span>
594+
<span class="badge badge-primary" title="Allowed Project Role">project_manager</span>
559595
</div>
560596

561597
<div>
@@ -573,24 +609,20 @@ <h2 class="anchor-container">
573609
<div class="row border-top">
574610
<div class="col py-2">
575611
<div class="permission-title anchor-container">
576-
<a href="#DELETE_PROJECT_MEMBER_NON_CUSTOMER" name="DELETE_PROJECT_MEMBER_NON_CUSTOMER" class="anchor"></a>Delete Project Member (non-customer)
612+
<a href="#DELETE_PROJECT_MEMBER_COPILOT" name="DELETE_PROJECT_MEMBER_COPILOT" class="anchor"></a>Delete Project Member (copilot)
577613
</div>
578-
<div class="permission-variable"><small><code>DELETE_PROJECT_MEMBER_NON_CUSTOMER</code></small></div>
579-
<div class="text-black-50 small-text">Who can delete project members with non &quot;customer&quot; role.</div>
614+
<div class="permission-variable"><small><code>DELETE_PROJECT_MEMBER_COPILOT</code></small></div>
615+
<div class="text-black-50 small-text">Who can delete project members with &quot;copilot&quot; role.</div>
580616
</div>
581617
<div class="col-9 py-2">
582618
<div>
583-
<span class="badge badge-primary" title="Allowed Project Role">manager</span>
584-
<span class="badge badge-primary" title="Allowed Project Role">account_manager</span>
585-
<span class="badge badge-primary" title="Allowed Project Role">program_manager</span>
586-
<span class="badge badge-primary" title="Allowed Project Role">account_executive</span>
587-
<span class="badge badge-primary" title="Allowed Project Role">solution_architect</span>
588-
<span class="badge badge-primary" title="Allowed Project Role">project_manager</span>
619+
<span class="badge badge-primary" title="Allowed">Any Project Member</span>
589620
</div>
590621

591622
<div>
592623
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
593624
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
625+
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Copilot Manager</span>
594626
</div>
595627

596628
<div>
@@ -680,15 +712,6 @@ <h2 class="anchor-container">
680712
<div>
681713
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
682714
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
683-
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Manager</span>
684-
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Account Manager</span>
685-
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Copilot Manager</span>
686-
<span class="badge badge-success" title="Allowed Topcoder Role">Business Development Representative</span>
687-
<span class="badge badge-success" title="Allowed Topcoder Role">Presales</span>
688-
<span class="badge badge-success" title="Allowed Topcoder Role">Account Executive</span>
689-
<span class="badge badge-success" title="Allowed Topcoder Role">Program Manager</span>
690-
<span class="badge badge-success" title="Allowed Topcoder Role">Solution Architect</span>
691-
<span class="badge badge-success" title="Allowed Topcoder Role">Project Manager</span>
692715
</div>
693716

694717
<div>
@@ -701,10 +724,10 @@ <h2 class="anchor-container">
701724
<div class="row border-top">
702725
<div class="col py-2">
703726
<div class="permission-title anchor-container">
704-
<a href="#CREATE_PROJECT_INVITE_NON_CUSTOMER" name="CREATE_PROJECT_INVITE_NON_CUSTOMER" class="anchor"></a>Create Project Invite (non-customer)
727+
<a href="#CREATE_PROJECT_INVITE_TOPCODER" name="CREATE_PROJECT_INVITE_TOPCODER" class="anchor"></a>Create Project Invite (topcoder)
705728
</div>
706-
<div class="permission-variable"><small><code>CREATE_PROJECT_INVITE_NON_CUSTOMER</code></small></div>
707-
<div class="text-black-50 small-text">Who can invite project members with non &quot;customer&quot; role.</div>
729+
<div class="permission-variable"><small><code>CREATE_PROJECT_INVITE_TOPCODER</code></small></div>
730+
<div class="text-black-50 small-text">Who can invite project members with topcoder role like &quot;manager&quot; etc.</div>
708731
</div>
709732
<div class="col-9 py-2">
710733
<div>
@@ -731,9 +754,9 @@ <h2 class="anchor-container">
731754
<div class="row border-top">
732755
<div class="col py-2">
733756
<div class="permission-title anchor-container">
734-
<a href="#CREATE_PROJECT_INVITE_COPILOT_DIRECTLY" name="CREATE_PROJECT_INVITE_COPILOT_DIRECTLY" class="anchor"></a>Create Project Invite (copilot)
757+
<a href="#CREATE_PROJECT_INVITE_COPILOT" name="CREATE_PROJECT_INVITE_COPILOT" class="anchor"></a>Create Project Invite (copilot)
735758
</div>
736-
<div class="permission-variable"><small><code>CREATE_PROJECT_INVITE_COPILOT_DIRECTLY</code></small></div>
759+
<div class="permission-variable"><small><code>CREATE_PROJECT_INVITE_COPILOT</code></small></div>
737760
<div class="text-black-50 small-text">Who can invite user with &quot;copilot&quot; role directly without requesting.</div>
738761
</div>
739762
<div class="col-9 py-2">
@@ -876,10 +899,40 @@ <h2 class="anchor-container">
876899
<div class="row border-top">
877900
<div class="col py-2">
878901
<div class="permission-title anchor-container">
879-
<a href="#DELETE_PROJECT_INVITE_NOT_OWN_NON_CUSTOMER" name="DELETE_PROJECT_INVITE_NOT_OWN_NON_CUSTOMER" class="anchor"></a>Delete Project Invite (not own, non-customer)
902+
<a href="#DELETE_PROJECT_INVITE_NOT_OWN_TOPCODER" name="DELETE_PROJECT_INVITE_NOT_OWN_TOPCODER" class="anchor"></a>Delete Project Invite (not own, topcoder)
903+
</div>
904+
<div class="permission-variable"><small><code>DELETE_PROJECT_INVITE_NOT_OWN_TOPCODER</code></small></div>
905+
<div class="text-black-50 small-text">Who can delete project invites for other members with some topcoder role like &quot;manager&quot; etc.</div>
906+
</div>
907+
<div class="col-9 py-2">
908+
<div>
909+
<span class="badge badge-primary" title="Allowed Project Role">manager</span>
910+
<span class="badge badge-primary" title="Allowed Project Role">account_manager</span>
911+
<span class="badge badge-primary" title="Allowed Project Role">program_manager</span>
912+
<span class="badge badge-primary" title="Allowed Project Role">account_executive</span>
913+
<span class="badge badge-primary" title="Allowed Project Role">solution_architect</span>
914+
<span class="badge badge-primary" title="Allowed Project Role">project_manager</span>
915+
</div>
916+
917+
<div>
918+
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
919+
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
920+
</div>
921+
922+
<div>
923+
<span class="badge badge-dark" title="Allowed Topcoder Role">all:connect_project</span>
924+
<span class="badge badge-dark" title="Allowed Topcoder Role">all:project-invites</span>
925+
<span class="badge badge-dark" title="Allowed Topcoder Role">write:project-invites</span>
926+
</div>
927+
</div>
928+
</div>
929+
<div class="row border-top">
930+
<div class="col py-2">
931+
<div class="permission-title anchor-container">
932+
<a href="#DELETE_PROJECT_INVITE_NOT_OWN_COPILOT" name="DELETE_PROJECT_INVITE_NOT_OWN_COPILOT" class="anchor"></a>Delete Project Invite (not own, copilot)
880933
</div>
881-
<div class="permission-variable"><small><code>DELETE_PROJECT_INVITE_NOT_OWN_NON_CUSTOMER</code></small></div>
882-
<div class="text-black-50 small-text">Who can delete project invites for other members with non &quot;customer&quot; role.</div>
934+
<div class="permission-variable"><small><code>DELETE_PROJECT_INVITE_NOT_OWN_COPILOT</code></small></div>
935+
<div class="text-black-50 small-text">Who can delete invites for other members with &quot;copilot&quot; role.</div>
883936
</div>
884937
<div class="col-9 py-2">
885938
<div>
@@ -894,6 +947,7 @@ <h2 class="anchor-container">
894947
<div>
895948
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Admin</span>
896949
<span class="badge badge-success" title="Allowed Topcoder Role">administrator</span>
950+
<span class="badge badge-success" title="Allowed Topcoder Role">Connect Copilot Manager</span>
897951
</div>
898952

899953
<div>

‎src/events/kafkaHandlers.js

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
/**
22
* BUS Event Handlers
33
*/
4-
import { CONNECT_NOTIFICATION_EVENT, BUS_API_EVENT, RESOURCES } from '../constants';
54
import {
6-
projectCreatedKafkaHandler,
7-
projectUpdatedKafkaHandler } from './projects';
8-
import { projectPhaseAddedKafkaHandler, projectPhaseRemovedKafkaHandler,
9-
projectPhaseUpdatedKafkaHandler } from './projectPhases';
5+
CONNECT_NOTIFICATION_EVENT,
6+
BUS_API_EVENT,
7+
RESOURCES,
8+
} from '../constants';
109
import {
11-
timelineAdjustedKafkaHandler,
12-
} from './timelines';
10+
projectCreatedKafkaHandler,
11+
projectUpdatedKafkaHandler,
12+
} from './projects';
1313
import {
14-
milestoneUpdatedKafkaHandler,
15-
} from './milestones';
14+
projectPhaseAddedKafkaHandler,
15+
projectPhaseRemovedKafkaHandler,
16+
projectPhaseUpdatedKafkaHandler,
17+
} from './projectPhases';
18+
import { timelineAdjustedKafkaHandler } from './timelines';
19+
import { milestoneUpdatedKafkaHandler } from './milestones';
1620

1721
const kafkaHandlers = {
1822
/**
@@ -33,22 +37,64 @@ const kafkaHandlers = {
3337
// Events coming from timeline/milestones (considering it as a separate module/service in future)
3438
[CONNECT_NOTIFICATION_EVENT.MILESTONE_TRANSITION_COMPLETED]: milestoneUpdatedKafkaHandler,
3539
[CONNECT_NOTIFICATION_EVENT.TIMELINE_ADJUSTED]: timelineAdjustedKafkaHandler,
40+
};
3641

37-
/**
38-
* New Unified Bus Events
39-
*/
40-
[BUS_API_EVENT.PROJECT_CREATED]: {
41-
[RESOURCES.PROJECT]: projectCreatedKafkaHandler,
42-
},
43-
[BUS_API_EVENT.PROJECT_PHASE_CREATED]: {
44-
[RESOURCES.PHASE]: projectPhaseAddedKafkaHandler,
45-
},
46-
[BUS_API_EVENT.PROJECT_PHASE_UPDATED]: {
47-
[RESOURCES.PHASE]: projectPhaseUpdatedKafkaHandler,
48-
},
49-
[BUS_API_EVENT.PROJECT_PHASE_DELETED]: {
50-
[RESOURCES.PHASE]: projectPhaseRemovedKafkaHandler,
51-
},
42+
/**
43+
* Register New Unified Bus Event Handlers
44+
*
45+
* We need this special method so it would properly merge topics with the same names
46+
* but different resources.
47+
*
48+
* @param {String} topic Kafka topic name
49+
* @param {String} resource resource name
50+
* @param {Function} handler handler method
51+
*
52+
* @returns {void}
53+
*/
54+
const registerKafkaHandler = (topic, resource, handler) => {
55+
let topicConfig = kafkaHandlers[topic];
56+
57+
// if config for topic is not yet initialized, create it
58+
if (!topicConfig) {
59+
topicConfig = {};
60+
kafkaHandlers[topic] = topicConfig;
61+
}
62+
63+
if (typeof topicConfig !== 'object') {
64+
throw new Error(
65+
`Topic "${topic}" should be defined as object with resource names as keys.`,
66+
);
67+
}
68+
69+
if (topicConfig[resource]) {
70+
throw new Error(
71+
`Handler for topic "${topic}" with resource ${resource} has been already registered.`,
72+
);
73+
}
74+
75+
topicConfig[resource] = handler;
5276
};
5377

78+
registerKafkaHandler(
79+
BUS_API_EVENT.PROJECT_CREATED,
80+
RESOURCES.PROJECT,
81+
projectCreatedKafkaHandler,
82+
);
83+
registerKafkaHandler(
84+
BUS_API_EVENT.PROJECT_PHASE_CREATED,
85+
RESOURCES.PHASE,
86+
projectPhaseAddedKafkaHandler,
87+
);
88+
registerKafkaHandler(
89+
BUS_API_EVENT.PROJECT_PHASE_UPDATED,
90+
RESOURCES.PHASE,
91+
projectPhaseUpdatedKafkaHandler,
92+
);
93+
registerKafkaHandler(
94+
BUS_API_EVENT.PROJECT_PHASE_DELETED,
95+
RESOURCES.PHASE,
96+
projectPhaseRemovedKafkaHandler,
97+
);
98+
99+
54100
export default kafkaHandlers;

0 commit comments

Comments
 (0)
Please sign in to comment.