Skip to content

Commit fc8e067

Browse files
feature: implement legacy challenge update (#6)
* feat: add project, resource, payment schema * fix: use id_column, id_sequence from schema definition * feat: use @topcoder-framework/lib-client for rdb types * feat: switch to @topcoder-framework/lib-common and @topcoder-framwork/client-relational Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * feat: add type information to schema * feat(domain-acl): complete challenge update interfaces * fix(acl): change folder naming convention * fix(domain-acl): create closeChallenge method * fix(domain-acl): fix reviewer type * refactor: use v0.0.13 proto definitions * fix(domain-acl): add audit properties where needed * fix(domain-acl): complete activateChallenge * refactor: use v0.0.14 proto definitions Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * correct imports * add prize service * feat: implement challenge:create * fixes for challenge update * fix(domain-acl): fixes for challenge update * remove audit fields * feat(ci): setup circleci (#7) * fix: docker build Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * feat: add circleci config to publish image to ecr Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * refactor: unify utils Signed-off-by: Rakib Ansary <rakibansary@gmail.com> --------- Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * chore: organize imports on save Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * chore: add pre-commit hook Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * ci: build & publish image to ecr Signed-off-by: Rakib Ansary <rakibansary@gmail.com> * feat: add linting * the rules being enforced are not as restrictive as Id like * but we will tighten the knobs in future Signed-off-by: Rakib Ansary <rakibansary@gmail.com> --------- Signed-off-by: Rakib Ansary <rakibansary@gmail.com> Co-authored-by: Thomas Kranitsas <thomas.kranitsas@topcoder.com>
1 parent 22e6a04 commit fc8e067

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+15048
-468
lines changed

.circleci/config.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
version: 2.1
2+
3+
jobs:
4+
publish-image:
5+
docker:
6+
- image: cimg/aws:2023.01
7+
environment:
8+
CODEARTIFACT_ENV: PROD
9+
ECR_ENV: QA
10+
SERVICE_NAME: "anticorruption-layer"
11+
OUT_DIR: "buildscripts"
12+
steps:
13+
- checkout
14+
- setup_remote_docker:
15+
docker_layer_caching: true
16+
- run:
17+
name: "Setup deploy scripts"
18+
command: |
19+
git clone -b v1.4 https://github.com/topcoder-platform/tc-deploy-scripts ../${OUT_DIR}
20+
cp ./../${OUT_DIR}/awsconfiguration.sh .
21+
- run:
22+
name: "Authenticate with AWS CodeArtifact and Build Docker Image"
23+
command: |
24+
./awsconfiguration.sh ${CODEARTIFACT_ENV}
25+
source awsenvconf
26+
aws codeartifact login --tool npm --repository topcoder-framework --domain topcoder --domain-owner $AWS_ACCOUNT_ID --region $AWS_REGION --namespace @topcoder-framework
27+
cp ~/.npmrc .
28+
rm -f awsenvconf
29+
docker build -t ${SERVICE_NAME}:${CIRCLE_SHA1} .
30+
- run:
31+
name: "Set AWS environment variables"
32+
command: |
33+
./awsconfiguration.sh ${ECR_ENV}
34+
- run:
35+
name: "Publish docker image"
36+
command: |
37+
source awsenvconf
38+
aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
39+
docker tag ${SERVICE_NAME}:${CIRCLE_SHA1} $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/${SERVICE_NAME}:${CIRCLE_SHA1}
40+
docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/${SERVICE_NAME}:${CIRCLE_SHA1}
41+
42+
workflows:
43+
version: 2
44+
publish:
45+
jobs:
46+
- "publish-image":
47+
context: "org-global"
48+
filters:
49+
branches:
50+
only: "feature/legacy-challenge"

.eslintignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
src/models/
2+
src/typings/
3+
node_modules/
4+
dist-cjs/
5+
dist-es/

.eslintrc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"env": {
3+
"es2022": true
4+
},
5+
"plugins": ["@typescript-eslint", "prettier"],
6+
"extends": [
7+
"eslint:recommended",
8+
"plugin:@typescript-eslint/recommended",
9+
"plugin:@typescript-eslint/recommended-requiring-type-checking",
10+
"prettier"
11+
],
12+
"parser": "@typescript-eslint/parser",
13+
"parserOptions": {
14+
"ecmaVersion": 2022,
15+
"project": "./tsconfig.json"
16+
},
17+
"rules": {
18+
"prefer-const": "error",
19+
"@typescript-eslint/no-explicit-any": "warn",
20+
"@typescript-eslint/no-unsafe-argument": "warn",
21+
"@typescript-eslint/no-unsafe-member-access": "warn"
22+
}
23+
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ dist/
44
.env
55
.DS_Store
66
.npmrc
7+
yarn-error.log

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
npx lint-staged

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"printWidth": 100
2+
"printWidth": 100,
3+
"organizeImportsSkipDestructiveCodeActions": true
34
}

Dockerfile

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
FROM node:18.11.0-alpine3.16 as ts-compile
2-
WORKDIR /usr/tc-acl
1+
FROM node:18.14.1-alpine3.17 as ts-compile
2+
WORKDIR /usr/anticorruption-layer
3+
COPY yarn*.lock ./
34
COPY package*.json ./
45
COPY tsconfig*.json ./
5-
RUN npm install
6+
COPY .npmrc ./
7+
RUN yarn install --frozen-lockfile --production=false
68
COPY . ./
7-
RUN npm run build:app
9+
RUN yarn build:app
810

9-
FROM node:18.11.0-alpine3.16 as ts-remove
10-
WORKDIR /usr/tc-acl
11-
COPY --from=ts-compile /usr/tc-acl/package*.json ./
12-
COPY --from=ts-compile /usr/tc-acl/dist ./
13-
RUN npm install --omit=dev
11+
FROM node:18.14.1-alpine3.17 as ts-remove
12+
WORKDIR /usr/anticorruption-layer
13+
COPY --from=ts-compile /usr/anticorruption-layer/yarn*.lock ./
14+
COPY --from=ts-compile /usr/anticorruption-layer/package*.json ./
15+
COPY --from=ts-compile /usr/anticorruption-layer/dist ./
16+
COPY --from=ts-compile /usr/anticorruption-layer/.npmrc ./
17+
RUN yarn install --frozen-lockfile --production=false
1418

1519
FROM gcr.io/distroless/nodejs:18
16-
WORKDIR /usr/tc-acl
17-
COPY --from=ts-remove /usr/tc-acl ./
20+
WORKDIR /usr/anticorruption-layer
21+
COPY --from=ts-remove /usr/anticorruption-layer ./
1822
USER 1000
23+
ENV GRPC_SERVER_PORT=40020
24+
ENV GRPC_SERVER_HOST=localhost
25+
ENV GRPC_RDB_SERVER_HOST=localhost
26+
ENV GRPC_RDB_SERVER_PORT=9090
1927
CMD ["server.js"]
20-
21-

bin/server.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const protoConfig = [
1919
`--plugin=${PLUGIN_PATH}`,
2020
// https://github.com/stephenh/ts-proto/blob/main/README.markdown
2121
"--ts_proto_opt=outputServices=grpc-js,env=node,useOptionals=messages,exportCommonSymbols=false,esModuleInterop=true",
22-
`--ts_proto_opt=stringEnums=true`,
2322
`--ts_proto_opt=useDate=string`,
2423
`--ts_proto_opt=oneof=unions`,
2524
`--ts_proto_opt=addGrpcMetadata=true`,

package.json

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,60 @@
99
"build:app": "rimraf dist && tsc -b",
1010
"build": "node bin/server && rimraf dist && tsc -b",
1111
"clean": "rimraf dist",
12-
"start": "ts-node-dev --respawn --transpile-only src/server.ts"
12+
"start": "ts-node-dev --respawn --transpile-only src/server.ts",
13+
"prepare": "husky install",
14+
"lint": "yarn eslint src --ext ts"
1315
},
14-
"keywords": [],
16+
"keywords": [
17+
"Topcoder",
18+
"Anticorruption Layer",
19+
"Topcoder Platform",
20+
"Topcoder gRPC Service"
21+
],
1522
"author": "Rakib Ansary <rakibansary@topcoder.com>",
1623
"license": "ISC",
1724
"dependencies": {
1825
"@grpc/grpc-js": "^1.7.1",
19-
"@topcoder-framework/client-relational": "^0.4.24-ci.0",
20-
"@topcoder-framework/lib-common": "^0.4.24-ci.0",
26+
"@topcoder-framework/client-relational": "^0.4.3",
27+
"@topcoder-framework/lib-common": "^0.4.3",
2128
"dayjs": "^1.11.5",
2229
"dotenv": "^16.0.3",
2330
"grpc-server-reflection": "^0.1.5",
2431
"lodash": "^4.17.21",
32+
"moment": "^2.29.4",
2533
"source-map-support": "^0.5.21",
26-
"topcoder-interface": "github:topcoder-platform/plat-interface-definition#v0.0.11",
34+
"topcoder-interface": "github:topcoder-platform/plat-interface-definition#v0.0.19",
2735
"uuidv4": "^6.2.13"
2836
},
2937
"devDependencies": {
38+
"@commitlint/cli": "^17.3.0",
39+
"@commitlint/config-conventional": "^17.3.0",
40+
"@commitlint/config-lerna-scopes": "^17.2.1",
3041
"@types/lodash": "^4.14.186",
3142
"@types/node": "18.11.18",
43+
"@typescript-eslint/eslint-plugin": "^5.47.1",
44+
"@typescript-eslint/parser": "^5.47.1",
45+
"commitlint": "^17.3.0",
46+
"eslint": "^8.30.0",
47+
"eslint-config-prettier": "^8.5.0",
48+
"eslint-plugin-prettier": "^4.2.1",
49+
"husky": "^8.0.0",
50+
"lint-staged": "^13.1.2",
51+
"prettier": "^2.8.1",
52+
"prettier-plugin-organize-imports": "^3.2.2",
3253
"ts-node-dev": "^2.0.0",
3354
"ts-proto": "^1.126.1",
3455
"typescript": "^4.9.4"
3556
},
57+
"lint-staged": {
58+
"*.{ts,tsx}": [
59+
"npx prettier --write",
60+
"npx eslint --fix"
61+
],
62+
"*.{json,md,yml}": [
63+
"npx prettier --write"
64+
]
65+
},
3666
"volta": {
3767
"node": "18.13.0",
3868
"yarn": "1.22.19"

src/common/Util.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { Row, Value as RelationalValue } from "@topcoder-framework/client-relational";
12
import { Operator, ScanCriteria, Value } from "@topcoder-framework/lib-common";
3+
import _ from "lodash";
24

35
export class Util {
46
public static toScanCriteria(criteria: { [key: string]: any }): ScanCriteria[] {
@@ -11,4 +13,76 @@ export class Util {
1113
} as ScanCriteria)
1214
);
1315
}
16+
17+
public static toIntValue(val: number): RelationalValue {
18+
return {
19+
value: {
20+
$case: "intValue",
21+
intValue: val,
22+
},
23+
};
24+
}
25+
26+
public static toFloatValue(val: number): RelationalValue {
27+
return {
28+
value: {
29+
$case: "floatValue",
30+
floatValue: val,
31+
},
32+
};
33+
}
34+
35+
public static toStringValue(val: string): RelationalValue {
36+
return {
37+
value: {
38+
$case: "stringValue",
39+
stringValue: val,
40+
},
41+
};
42+
}
43+
44+
public static toDatetimeValue(val: string): RelationalValue {
45+
return {
46+
value: {
47+
$case: "datetimeValue",
48+
datetimeValue: val,
49+
},
50+
};
51+
}
52+
53+
public static parseRow(row: Row): any {
54+
const obj: any = {};
55+
for (const key of Object.keys(row.values)) {
56+
if (row.values[key].value?.$case) {
57+
obj[_.camelCase(key)] = _.get(row.values[key].value, row.values[key].value!.$case);
58+
}
59+
}
60+
return obj;
61+
}
62+
63+
public static formatDate(str: string | undefined) {
64+
if (str == null || str.length == 0) {
65+
return undefined;
66+
}
67+
try {
68+
const date = new Date(str);
69+
const year = date.getFullYear();
70+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
71+
const day = date.getDate().toString().padStart(2, "0");
72+
const hours = date.getHours().toString().padStart(2, "0");
73+
const minutes = date.getMinutes().toString().padStart(2, "0");
74+
const seconds = date.getSeconds().toString().padStart(2, "0");
75+
const milliseconds = date.getMilliseconds().toString().padStart(3, "0");
76+
77+
return (
78+
[year, month, day].join("-") +
79+
" " +
80+
[hours, minutes, seconds].join(":") +
81+
"." +
82+
milliseconds
83+
);
84+
} catch {
85+
return undefined;
86+
}
87+
}
1488
}

src/config/constants.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
export const PhaseStatusIds = {
2+
Scheduled: 1,
3+
Open: 2,
4+
Closed: 3,
5+
};
6+
7+
export const PhaseTypeIds = {
8+
Submission: 2,
9+
Review: 4,
10+
IterativeReview: 18,
11+
SpecificationSubmission: 13,
12+
};
13+
14+
export const ProjectCategories = {
15+
First2Finish: 38,
16+
};
17+
18+
export const ResourceRoleTypeIds = {
19+
Submitter: 1,
20+
PrimaryScreener: 2,
21+
Screener: 3,
22+
Reviewer: 4,
23+
Approver: 10,
24+
Designer: 11,
25+
Observer: 12,
26+
Manager: 13,
27+
Copilot: 14,
28+
ClientManager: 15,
29+
PostMortemReviewer: 16,
30+
SpecificationSubmitter: 17,
31+
SpecificationReviewer: 18,
32+
CheckpointScreener: 19,
33+
CheckpointReviewer: 20,
34+
IterativeReviewer: 21,
35+
};
36+
37+
export const ResourceInfoTypeIds = {
38+
ExternalReferenceId: 1,
39+
Handle: 2,
40+
Email: 3,
41+
Rating: 4,
42+
Reliability: 5,
43+
RegistrationDate: 6,
44+
Payment: 7,
45+
PaymentStatus: 8,
46+
ScreeningScore: 9,
47+
InitialScore: 10,
48+
FinalScore: 11,
49+
Placement: 12,
50+
AppealsCompletedEarly: 13,
51+
SVNPermissionAdded: 14,
52+
ManualPayments: 15,
53+
};
54+
55+
type ResourceInfoTypeIds = keyof typeof ResourceInfoTypeIds;
56+
57+
export const ObserverResourceInfoToAdd: ResourceInfoTypeIds[] = [
58+
"ExternalReferenceId",
59+
"Handle",
60+
"RegistrationDate",
61+
"PaymentStatus",
62+
"AppealsCompletedEarly",
63+
];

0 commit comments

Comments
 (0)