From fb68580f86687a93945e6f4910e648e90e6e2de9 Mon Sep 17 00:00:00 2001 From: Andrew Besedin Date: Wed, 18 Feb 2026 21:00:40 +0300 Subject: [PATCH 1/2] update: add pairs obsolete filter --- src/models/Dex.ts | 87 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/src/models/Dex.ts b/src/models/Dex.ts index fde4f98..0a1174b 100644 --- a/src/models/Dex.ts +++ b/src/models/Dex.ts @@ -38,8 +38,44 @@ class DexModel { } private getPairsSearchCondition(searchText: string, whitelistedOnly: boolean) { + const tickerRegexp = /^[A-Za-z0-9]{1,14}$/; + const fullNameRegexp = /^[A-Za-z0-9.,:!?\-() ]{0,255}$/; + + const firstFullNameExpr = Sequelize.literal(`"first_currency"."asset_info"->>'full_name'`); + const secondFullNameExpr = Sequelize.literal( + `"second_currency"."asset_info"->>'full_name'`, + ); + const searchCondition: WhereOptions = { [Op.and]: [ + Sequelize.where(Sequelize.col('first_currency.name'), { + [Op.regexp]: tickerRegexp.source, + }), + { + [Op.or]: [ + Sequelize.where(Sequelize.col('first_currency.asset_info'), { + [Op.is]: null, + }), + Sequelize.where(firstFullNameExpr, { [Op.is]: null }), + Sequelize.where(firstFullNameExpr, { + [Op.regexp]: fullNameRegexp.source, + }), + ], + }, + Sequelize.where(Sequelize.col('second_currency.name'), { + [Op.regexp]: tickerRegexp.source, + }), + { + [Op.or]: [ + Sequelize.where(Sequelize.col('second_currency.asset_info'), { + [Op.is]: null, + }), + Sequelize.where(secondFullNameExpr, { [Op.is]: null }), + Sequelize.where(secondFullNameExpr, { + [Op.regexp]: fullNameRegexp.source, + }), + ], + }, { [Op.or]: [ Sequelize.where( @@ -70,7 +106,20 @@ class DexModel { ], }; - return searchCondition; + const includeCondition = [ + { + model: Currency, + as: 'first_currency', + attributes: ['asset_id', 'code', 'id', 'name', 'type', 'whitelisted'], + }, + { + model: Currency, + as: 'second_currency', + attributes: ['asset_id', 'code', 'id', 'name', 'type', 'whitelisted'], + }, + ]; + + return { searchCondition, includeCondition }; } async getPairRow(id: number) { @@ -88,7 +137,10 @@ class DexModel { sortOption: PairSortOption, ) { try { - const searchCondition = this.getPairsSearchCondition(searchText, whitelistedOnly); + const { searchCondition, includeCondition } = this.getPairsSearchCondition( + searchText, + whitelistedOnly, + ); const volumeSortDirection = sortOption === PairSortOption.VOLUME_LOW_TO_HIGH ? 'ASC' : 'DESC'; @@ -105,18 +157,7 @@ class DexModel { 'volume', 'featured', ], - include: [ - { - model: Currency, - as: 'first_currency', - attributes: ['asset_id', 'code', 'id', 'name', 'type', 'whitelisted'], - }, - { - model: Currency, - as: 'second_currency', - attributes: ['asset_id', 'code', 'id', 'name', 'type', 'whitelisted'], - }, - ], + include: includeCondition, where: searchCondition, order: [ ['volume', volumeSortDirection], @@ -152,21 +193,13 @@ class DexModel { async getPairsPagesAmount(searchText: string, whitelistedOnly: boolean) { try { - const searchCondition = this.getPairsSearchCondition(searchText, whitelistedOnly); + const { searchCondition, includeCondition } = this.getPairsSearchCondition( + searchText, + whitelistedOnly, + ); const count = await Pair.count({ - include: [ - { - model: Currency, - as: 'first_currency', - attributes: ['asset_id', 'code', 'id', 'name', 'type'], - }, - { - model: Currency, - as: 'second_currency', - attributes: ['asset_id', 'code', 'id', 'name', 'type'], - }, - ], + include: includeCondition, where: searchCondition, }); From d3b762d6e9a6a8773a19fd94dc2d8c2b65635163 Mon Sep 17 00:00:00 2001 From: Andrew Besedin Date: Wed, 18 Feb 2026 21:36:18 +0300 Subject: [PATCH 2/2] update: update pair currencies full_name length validation for char_length 400 --- src/models/Dex.ts | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/models/Dex.ts b/src/models/Dex.ts index 0a1174b..740c79e 100644 --- a/src/models/Dex.ts +++ b/src/models/Dex.ts @@ -39,7 +39,7 @@ class DexModel { private getPairsSearchCondition(searchText: string, whitelistedOnly: boolean) { const tickerRegexp = /^[A-Za-z0-9]{1,14}$/; - const fullNameRegexp = /^[A-Za-z0-9.,:!?\-() ]{0,255}$/; + const fullNameRegexp = /^[A-Za-z0-9.,:!?\-() ]*$/; const firstFullNameExpr = Sequelize.literal(`"first_currency"."asset_info"->>'full_name'`); const secondFullNameExpr = Sequelize.literal( @@ -57,9 +57,16 @@ class DexModel { [Op.is]: null, }), Sequelize.where(firstFullNameExpr, { [Op.is]: null }), - Sequelize.where(firstFullNameExpr, { - [Op.regexp]: fullNameRegexp.source, - }), + { + [Op.and]: [ + Sequelize.where(firstFullNameExpr, { + [Op.regexp]: fullNameRegexp.source, + }), + Sequelize.where(Sequelize.fn('char_length', firstFullNameExpr), { + [Op.lte]: 400, + }), + ], + }, ], }, Sequelize.where(Sequelize.col('second_currency.name'), { @@ -71,9 +78,16 @@ class DexModel { [Op.is]: null, }), Sequelize.where(secondFullNameExpr, { [Op.is]: null }), - Sequelize.where(secondFullNameExpr, { - [Op.regexp]: fullNameRegexp.source, - }), + { + [Op.and]: [ + Sequelize.where(secondFullNameExpr, { + [Op.regexp]: fullNameRegexp.source, + }), + Sequelize.where(Sequelize.fn('char_length', secondFullNameExpr), { + [Op.lte]: 400, + }), + ], + }, ], }, {