From 60a37a7d34d32968175a6cb47f39a4da02ce0638 Mon Sep 17 00:00:00 2001 From: Rakib Ansary Date: Tue, 11 Apr 2023 15:11:31 +0600 Subject: [PATCH 1/5] fix: search * use es scroll api to ensure all results are fetched --- .circleci/config.yml | 4 +-- README.md | 6 ++--- src/common/helper.js | 43 +++++++++++--------------------- src/services/ChallengeService.js | 3 --- 4 files changed, 18 insertions(+), 38 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 59cd7236..b2b4a25a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -83,14 +83,14 @@ workflows: branches: only: - dev - - fix/schema + - fix/search - "build-qa": context: org-global filters: branches: only: - - refactor/domain-challenge + - qa # Production builds are exectuted only on tagged commits to the # master branch. diff --git a/README.md b/README.md index 7ecd2b8b..4456de08 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,11 @@ Dev: [![CircleCI](https://circleci.com/gh/topcoder-platform/challenge-api/tree/d - [Resources API](https://github.com/topcoder-platform/resources-api) - [ES Processor](https://github.com/topcoder-platform/challenge-processor-es) - Updates data in ElasticSearch -- [Legacy Processor](https://github.com/topcoder-platform/legacy-challenge-processor) - Moves data from DynamoDB back to Informix -- [Legacy Migration Script](https://github.com/topcoder-platform/legacy-challenge-migration-script) - Moves data from Informix to DynamoDB -- [Frontend App](https://github.com/topcoder-platform/challenge-engine-ui) +- [Domain Challenge](https://github.com/topcoder-platform/domain-challenge) - Domain Challenge ## Prerequisites -- [NodeJS](https://nodejs.org/en/) (v10) +- [NodeJS](https://nodejs.org/en/) (v18+) - [AWS S3](https://aws.amazon.com/s3/) - [Elasticsearch v6](https://www.elastic.co/) - [Docker](https://www.docker.com/) diff --git a/src/common/helper.js b/src/common/helper.js index 33044085..1a7cc32a 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -754,36 +754,21 @@ function calculateChallengeEndDate(challenge, data) { async function listChallengesByMember(memberId) { const token = await m2mHelper.getM2MToken(); let allIds = []; - // get search is paginated, we need to get all pages' data - let page = 1; - while (true) { - let result = {}; - try { - result = await axios.get(`${config.RESOURCES_API_URL}/${memberId}/challenges`, { - headers: { Authorization: `Bearer ${token}` }, - params: { - page, - perPage: 10000, - }, - }); - } catch (e) { - // only log the error but don't throw it, so the following logic can still be executed. - logger.debug(`Failed to get challenges that accessible to the memberId ${memberId}`, e); - } - const ids = result.data || []; - if (ids.length === 0) { - break; - } - allIds = allIds.concat(ids); - page += 1; - if ( - result.headers && - result.headers["x-total-pages"] && - page > Number(result.headers["x-total-pages"]) - ) { - break; - } + + try { + const result = await axios.get(`${config.RESOURCES_API_URL}/${memberId}/challenges`, { + headers: { Authorization: `Bearer ${token}` }, + params: { + useScroll: true, + }, + }); + + allIds = result.data || []; + } catch (e) { + // only log the error but don't throw it, so the following logic can still be executed. + logger.debug(`Failed to get challenges that accessible to the memberId ${memberId}`, e); } + return allIds; } diff --git a/src/services/ChallengeService.js b/src/services/ChallengeService.js index f593b684..9868f964 100644 --- a/src/services/ChallengeService.js +++ b/src/services/ChallengeService.js @@ -149,7 +149,6 @@ async function searchChallenges(currentUser, criteria) { _.includes(config.SELF_SERVICE_WHITELIST_HANDLES, currentUser.handle.toLowerCase())); const includedTrackIds = _.isArray(criteria.trackIds) ? criteria.trackIds : []; - const includedTypeIds = _.isArray(criteria.typeIds) ? criteria.typeIds : []; if (criteria.type) { @@ -168,7 +167,6 @@ async function searchChallenges(currentUser, criteria) { criteria.trackId = _.get(trackSearchRes, "result[0].id"); } } - if (criteria.types) { for (const t of criteria.types) { const typeSearchRes = await ChallengeTypeService.searchChallengeTypes({ abbreviation: t }); @@ -187,7 +185,6 @@ async function searchChallenges(currentUser, criteria) { } } } - if (criteria.typeId) { includedTypeIds.push(criteria.typeId); } From 80eabba3d0406aa0d1fade92e2a2a4f11d7b588d Mon Sep 17 00:00:00 2001 From: Rakib Ansary Date: Wed, 12 Apr 2023 03:15:56 +0600 Subject: [PATCH 2/5] fix: search by member id Signed-off-by: Rakib Ansary --- src/services/ChallengeService.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/ChallengeService.js b/src/services/ChallengeService.js index 9868f964..a163dbb6 100644 --- a/src/services/ChallengeService.js +++ b/src/services/ChallengeService.js @@ -601,10 +601,10 @@ async function searchChallenges(currentUser, criteria) { match_phrase: { "task.isAssigned": criteria.taskIsAssigned }, }); } - if (criteria.taskMemberId || criteria.memberId) { + if (criteria.taskMemberId) { boolQuery.push({ match_phrase: { - "task.memberId": criteria.taskMemberId || criteria.memberId, + "task.memberId": criteria.taskMemberId, }, }); } From a02a190365b58eda8d91cf97b0d5de1945b15df6 Mon Sep 17 00:00:00 2001 From: Rakib Ansary Date: Fri, 14 Apr 2023 13:32:45 +0600 Subject: [PATCH 3/5] fix: winner prize mismatch (plat-2732) Signed-off-by: Rakib Ansary --- package.json | 1 + src/common/challenge-helper.js | 14 +++++++++++--- yarn.lock | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7bb22c6c..c6cdb098 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "body-parser": "^1.15.1", "config": "^3.0.1", "cors": "^2.7.1", + "decimal.js": "^10.4.3", "deep-equal": "^2.2.0", "dotenv": "^8.2.0", "elasticsearch": "^16.7.3", diff --git a/src/common/challenge-helper.js b/src/common/challenge-helper.js index ce13b8f3..7ee93a08 100644 --- a/src/common/challenge-helper.js +++ b/src/common/challenge-helper.js @@ -8,6 +8,7 @@ const config = require("config"); const helper = require("./helper"); const constants = require("../../app-constants"); const axios = require("axios"); +const Decimal = require("decimal.js"); const { getM2MToken } = require("./m2m-helper"); const { hasAdminRole } = require("./role-helper"); const { ensureAcessibilityToModifiedGroups } = require("./group-helper"); @@ -350,7 +351,10 @@ class ChallengeHelper { convertPrizeSetValuesToCents(prizeSets) { prizeSets.forEach((prizeSet) => { prizeSet.prizes.forEach((prize) => { - prize.amountInCents = prize.value * 100; + prize.amountInCents = new Decimal(prize.value) + .mul(100) + .round(0, Decimal.ROUND_DOWN) + .toNumber(); delete prize.value; }); }); @@ -360,13 +364,17 @@ class ChallengeHelper { prizeSets.forEach((prizeSet) => { prizeSet.prizes.forEach((prize) => { if (prize.amountInCents != null) { - prize.value = prize.amountInCents / 100; + prize.value = parseFloat(new Decimal(prize.amountInCents).div(100).toFixed(2)); + delete prize.amountInCents; } }); }); if (overview && !_.isUndefined(overview.totalPrizesInCents)) { - overview.totalPrizes = overview.totalPrizesInCents / 100; + overview.totalPrizes = parseFloat( + new Decimal(overview.totalPrizesInCents).div(100).toFixed(2) + ); + delete overview.totalPrizesInCents; } } diff --git a/yarn.lock b/yarn.lock index 7d7fd30d..c2a451ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1058,6 +1058,11 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decimal.js@^10.4.3: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + deep-eql@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" From 2674f81e115f9647eb177768406a7f7e5db78ffa Mon Sep 17 00:00:00 2001 From: Rakib Ansary Date: Fri, 14 Apr 2023 13:33:41 +0600 Subject: [PATCH 4/5] ci: deploy to dev Signed-off-by: Rakib Ansary --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b2b4a25a..5e41ee80 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -83,7 +83,7 @@ workflows: branches: only: - dev - - fix/search + - fix/floating-point-arhithmetic - "build-qa": context: org-global From 84f4c0022f4b51e8052dbb71b9986f4947bcbc65 Mon Sep 17 00:00:00 2001 From: Rakib Ansary Date: Fri, 14 Apr 2023 14:11:26 +0600 Subject: [PATCH 5/5] fix: remove unnecessary rounding Signed-off-by: Rakib Ansary --- src/common/challenge-helper.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/common/challenge-helper.js b/src/common/challenge-helper.js index 7ee93a08..a7372149 100644 --- a/src/common/challenge-helper.js +++ b/src/common/challenge-helper.js @@ -351,10 +351,7 @@ class ChallengeHelper { convertPrizeSetValuesToCents(prizeSets) { prizeSets.forEach((prizeSet) => { prizeSet.prizes.forEach((prize) => { - prize.amountInCents = new Decimal(prize.value) - .mul(100) - .round(0, Decimal.ROUND_DOWN) - .toNumber(); + prize.amountInCents = new Decimal(prize.value).mul(100).toNumber(); delete prize.value; }); });