diff --git a/.circleci/config.yml b/.circleci/config.yml index 59cd7236..5e41ee80 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -83,14 +83,14 @@ workflows: branches: only: - dev - - fix/schema + - fix/floating-point-arhithmetic - "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/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..a7372149 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,7 @@ class ChallengeHelper { convertPrizeSetValuesToCents(prizeSets) { prizeSets.forEach((prizeSet) => { prizeSet.prizes.forEach((prize) => { - prize.amountInCents = prize.value * 100; + prize.amountInCents = new Decimal(prize.value).mul(100).toNumber(); delete prize.value; }); }); @@ -360,13 +361,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/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 f96c4a9e..309cb3cf 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); } @@ -604,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, }, }); } 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"