From 5dd89ed9b4732da524b9e0e16a90ddf1a9a518e5 Mon Sep 17 00:00:00 2001 From: jejolare Date: Sat, 31 Jan 2026 19:49:30 +0700 Subject: [PATCH 1/3] add orders expiration --- src/server.ts | 2 + src/workers/ordersModerationService.ts | 51 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/workers/ordersModerationService.ts diff --git a/src/server.ts b/src/server.ts index fe11e72..ed5f774 100644 --- a/src/server.ts +++ b/src/server.ts @@ -24,6 +24,7 @@ import statsRouter from './routes/stats.router'; import exchangeModel from './models/ExchangeTransactions'; import { setupAssociations } from './schemes/Associations'; import statsModel from './models/Stats'; +import ordersModerationService from './workers/ordersModerationService'; const PORT = process.env.PORT || 3000; @@ -71,6 +72,7 @@ process.on('unhandledRejection', (reason, promise) => { } assetsUpdateChecker.run(); + ordersModerationService.run(); exchangeModel.runPairStatsDaemon(); statsModel.init(); diff --git a/src/workers/ordersModerationService.ts b/src/workers/ordersModerationService.ts new file mode 100644 index 0000000..d619c56 --- /dev/null +++ b/src/workers/ordersModerationService.ts @@ -0,0 +1,51 @@ +import Order from '@/schemes/Order'; +import { Op } from 'sequelize'; + +const CHECKING_INTERVAL = 60 * 60 * 1000; // 1 hr +const ORDER_EXPIRATION_TIME = 30 * 24 * 60 * 60 * 1000; // 30 days + +class OrdersModerationService { + public async run() { + /* eslint-disable no-constant-condition */ + while (true) { + await this.handleOrdersExpirations(); + console.log( + `[${new Date()}] Orders moderation check is done. Next check in ${CHECKING_INTERVAL / 1000} sec.`, + ); + + await new Promise((resolve) => setTimeout(resolve, CHECKING_INTERVAL)); + } + /* eslint-enable no-constant-condition */ + } + + private async handleOrdersExpirations() { + const now = +Date.now(); + + const ordersToExpire = await Order.findAll({ + where: { + updatedAt: { + [Op.lte]: new Date(now - ORDER_EXPIRATION_TIME), + }, + status: 'active', + }, + }); + + const idsToExpire = ordersToExpire.map((order) => order.id); + + await Order.destroy({ + where: { + id: idsToExpire, + }, + }); + + if (idsToExpire.length > 0) { + console.log( + `[${new Date()}] Expired orders handled. Expired orders IDs: ${idsToExpire.join(', ')}`, + ); + } + } +} + +const ordersModerationService = new OrdersModerationService(); + +export default ordersModerationService; From cc8d282ea29c1c944d2b3c6761ab33702f5e6d70 Mon Sep 17 00:00:00 2001 From: jejolare Date: Sat, 31 Jan 2026 19:51:31 +0700 Subject: [PATCH 2/3] debug --- src/workers/ordersModerationService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/workers/ordersModerationService.ts b/src/workers/ordersModerationService.ts index d619c56..976e100 100644 --- a/src/workers/ordersModerationService.ts +++ b/src/workers/ordersModerationService.ts @@ -2,7 +2,9 @@ import Order from '@/schemes/Order'; import { Op } from 'sequelize'; const CHECKING_INTERVAL = 60 * 60 * 1000; // 1 hr -const ORDER_EXPIRATION_TIME = 30 * 24 * 60 * 60 * 1000; // 30 days +// const ORDER_EXPIRATION_TIME = 30 * 24 * 60 * 60 * 1000; // 30 days + +const ORDER_EXPIRATION_TIME = 60 * 1000; // for debug class OrdersModerationService { public async run() { From 9bea1e7bf3f47d3ade36c3e51c13645c4a1e1295 Mon Sep 17 00:00:00 2001 From: jejolare Date: Sat, 31 Jan 2026 19:55:41 +0700 Subject: [PATCH 3/3] check if order is instant before expiration --- src/workers/ordersModerationService.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/workers/ordersModerationService.ts b/src/workers/ordersModerationService.ts index 976e100..5758817 100644 --- a/src/workers/ordersModerationService.ts +++ b/src/workers/ordersModerationService.ts @@ -1,10 +1,9 @@ +import dexModel from '@/models/Dex'; import Order from '@/schemes/Order'; import { Op } from 'sequelize'; const CHECKING_INTERVAL = 60 * 60 * 1000; // 1 hr -// const ORDER_EXPIRATION_TIME = 30 * 24 * 60 * 60 * 1000; // 30 days - -const ORDER_EXPIRATION_TIME = 60 * 1000; // for debug +const ORDER_EXPIRATION_TIME = 30 * 24 * 60 * 60 * 1000; // 30 days class OrdersModerationService { public async run() { @@ -34,15 +33,17 @@ class OrdersModerationService { const idsToExpire = ordersToExpire.map((order) => order.id); + const notInstant = idsToExpire.filter((orderId) => !dexModel.isBotActive(orderId)); + await Order.destroy({ where: { - id: idsToExpire, + id: notInstant, }, }); - if (idsToExpire.length > 0) { + if (notInstant.length > 0) { console.log( - `[${new Date()}] Expired orders handled. Expired orders IDs: ${idsToExpire.join(', ')}`, + `[${new Date()}] Expired orders handled. Expired orders IDs: ${notInstant.join(', ')}`, ); } }