From f727edf50f4e7de2fee0f8beadec37dc52307156 Mon Sep 17 00:00:00 2001 From: David May <85513542+davidleomay@users.noreply.github.com> Date: Tue, 26 May 2026 15:29:18 +0200 Subject: [PATCH 1/4] fix: register Tron/Solana payment address with Tatum webhook (#3763) The payment deposit addresses for Tron and Solana were never registered with Tatum for webhook notifications, causing incoming transactions to go undetected and payment quotes to stay stuck in TxMempool state. Add hasAddressSubscription check to TatumWebhookService and include the payment deposit address when creating Tron/Solana deposit webhooks. --- .../tatum/services/tatum-webhook.service.ts | 11 +++++++++++ .../address-pool/deposit/deposit.service.ts | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/integration/tatum/services/tatum-webhook.service.ts b/src/integration/tatum/services/tatum-webhook.service.ts index f23ddd4048..79948b0325 100644 --- a/src/integration/tatum/services/tatum-webhook.service.ts +++ b/src/integration/tatum/services/tatum-webhook.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; import { Network as TatumNetwork, TatumSDK, Solana as TatumSolana, Tron as TatumTron } from '@tatumio/tatum'; import { Observable, Subject } from 'rxjs'; import { Config, Environment } from 'src/config/config'; +import { Blockchain } from 'src/integration/blockchain/shared/enums/blockchain.enum'; import { Util } from 'src/shared/utils/util'; import { CreateTatumWebhookDto, TatumWebhookDto } from '../dto/tatum.dto'; import { TatumNetworkMapper } from '../tatum-network-mapper'; @@ -56,6 +57,16 @@ export class TatumWebhookService { ).then((s) => s.map((s) => s.data.id)); } + async hasAddressSubscription(blockchain: Blockchain, address: string): Promise { + const network = TatumNetworkMapper.toTatumNetworkByBlockchain(blockchain); + if (!network) return false; + + const tatumSdk = await this.getTatumSdk(network); + const result = await tatumSdk.notification.getAll({ pageSize: 50, address }); + + return result.data?.length > 0; + } + getAddressWebhookObservable(): Observable { return this.addressWebhookSubject.asObservable(); } diff --git a/src/subdomains/supporting/address-pool/deposit/deposit.service.ts b/src/subdomains/supporting/address-pool/deposit/deposit.service.ts index 1122444a65..ec7fd30843 100644 --- a/src/subdomains/supporting/address-pool/deposit/deposit.service.ts +++ b/src/subdomains/supporting/address-pool/deposit/deposit.service.ts @@ -266,6 +266,11 @@ export class DepositService implements OnModuleInit { addresses.push(deposit.address); } + const paymentAddress = SolanaUtil.createWallet({ seed: Config.payment.solanaSeed, index: 0 }).address; + if (!(await this.tatumWebhookService.hasAddressSubscription(Blockchain.SOLANA, paymentAddress))) { + addresses.push(paymentAddress); + } + await this.tatumWebhookService.createAddressWebhook({ blockchain: Blockchain.SOLANA, addresses: addresses }); } @@ -284,6 +289,11 @@ export class DepositService implements OnModuleInit { addresses.push(deposit.address); } + const paymentAddress = TronUtil.createWallet({ seed: Config.payment.tronSeed, index: 0 }).address; + if (!(await this.tatumWebhookService.hasAddressSubscription(Blockchain.TRON, paymentAddress))) { + addresses.push(paymentAddress); + } + await this.tatumWebhookService.createAddressWebhook({ blockchain: Blockchain.TRON, addresses: addresses }); } From faa359ea3d5eae12d9c3d3bfbb8584ef064f6ccf Mon Sep 17 00:00:00 2001 From: David May <85513542+davidleomay@users.noreply.github.com> Date: Tue, 26 May 2026 15:41:45 +0200 Subject: [PATCH 2/4] perf: add indexes on all foreign key columns (#3762) PostgreSQL does not auto-create indexes on FK columns. Without them, every JOIN/WHERE on a FK does a sequential scan. This adds @Index() to all @ManyToOne relations (139 indexes). --- .../1779802432879-AddForeignKeyIndexes.js | 298 ++++++++++++++++++ src/shared/models/fiat/fiat.entity.ts | 3 +- src/shared/models/ip-log/ip-log.entity.ts | 4 +- src/shared/models/reward.entity.ts | 3 +- .../entities/buy-crypto-fees.entity.ts | 3 +- .../process/entities/buy-crypto.entity.ts | 5 +- .../core/buy-crypto/routes/buy/buy.entity.ts | 3 + .../buy-crypto/routes/swap/swap.entity.ts | 4 +- .../entities/custody-account-access.entity.ts | 2 + .../entities/custody-account.entity.ts | 3 +- .../entities/custody-balance.entity.ts | 3 + .../entities/custody-order-step.entity.ts | 3 +- .../custody/entities/custody-order.entity.ts | 3 +- .../entities/faucet-request.entity.ts | 5 +- .../liquidity-management-action.entity.ts | 4 +- .../liquidity-management-order.entity.ts | 4 +- .../liquidity-management-pipeline.entity.ts | 2 + .../liquidity-management-rule.entity.ts | 3 + .../entities/payment-activation.entity.ts | 3 + .../entities/payment-link-payment.entity.ts | 1 + .../entities/payment-link.entity.ts | 3 +- .../entities/payment-merchant.entity.ts | 3 +- .../entities/payment-quote.entity.ts | 3 +- .../core/referral/reward/ref-reward.entity.ts | 4 +- .../sell-crypto/process/buy-fiat.entity.ts | 7 +- .../core/sell-crypto/route/sell.entity.ts | 4 +- .../staking/entities/crypto-staking.entity.ts | 4 +- .../entities/staking-ref-reward.entity.ts | 4 +- .../staking/entities/staking-reward.entity.ts | 1 + .../core/staking/entities/staking.entity.ts | 6 +- .../trading/entities/trading-order.entity.ts | 5 +- .../trading/entities/trading-rule.entity.ts | 4 +- .../generic/kyc/entities/kyc-file.entity.ts | 4 +- .../generic/kyc/entities/kyc-log.entity.ts | 4 +- .../generic/kyc/entities/kyc-step.entity.ts | 1 + .../kyc/entities/name-check-log.entity.ts | 3 +- .../generic/kyc/entities/step-log.entity.ts | 3 +- .../account-merge/account-merge.entity.ts | 2 + .../user/models/bank-data/bank-data.entity.ts | 2 + .../organization/organization.entity.ts | 4 +- .../recommendation/recommendation.entity.ts | 4 +- .../user-data-relation.entity.ts | 4 +- .../user/models/user-data/user-data.entity.ts | 9 + .../generic/user/models/user/user.entity.ts | 6 + .../user/models/wallet/wallet.entity.ts | 1 + .../user/services/webhook/webhook.entity.ts | 5 +- .../bank-tx-repeat/bank-tx-repeat.entity.ts | 3 +- .../bank-tx-return/bank-tx-return.entity.ts | 3 +- .../bank-tx/entities/bank-tx.entity.ts | 3 +- .../bank/virtual-iban/virtual-iban.entity.ts | 4 + .../dex/entities/liquidity-order.entity.ts | 4 + .../fiat-output/fiat-output.entity.ts | 3 +- src/subdomains/supporting/mros/mros.entity.ts | 3 +- .../entities/notification.entity.ts | 3 +- .../payin/entities/crypto-input.entity.ts | 4 + .../supporting/payment/entities/fee.entity.ts | 4 +- .../entities/transaction-request.entity.ts | 3 +- .../transaction-risk-assessment.entity.ts | 3 +- .../payment/entities/transaction.entity.ts | 4 +- .../domain/entities/asset-price.entity.ts | 3 +- .../domain/entities/price-rule.entity.ts | 3 +- .../supporting/recall/recall.entity.ts | 3 + .../entities/limit-request-log.entity.ts | 3 +- .../entities/support-issue-log.entity.ts | 3 +- .../entities/support-issue.entity.ts | 5 +- .../entities/support-log.entity.ts | 3 +- .../entities/support-message.entity.ts | 3 +- 67 files changed, 481 insertions(+), 48 deletions(-) create mode 100644 migration/1779802432879-AddForeignKeyIndexes.js diff --git a/migration/1779802432879-AddForeignKeyIndexes.js b/migration/1779802432879-AddForeignKeyIndexes.js new file mode 100644 index 0000000000..c1a9da419c --- /dev/null +++ b/migration/1779802432879-AddForeignKeyIndexes.js @@ -0,0 +1,298 @@ +/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + * @typedef {import('typeorm').QueryRunner} QueryRunner + */ + +/** + * @class + * @implements {MigrationInterface} + */ +module.exports = class AddForeignKeyIndexes1779802432879 { + name = 'AddForeignKeyIndexes1779802432879' + + /** + * @param {QueryRunner} queryRunner + */ + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX "IDX_85d63658ee8348a72cc5704f9f" ON "price_rule" ("referenceId") `); + await queryRunner.query(`CREATE INDEX "IDX_498338cbab828a1938e283a16d" ON "fiat" ("priceRuleId") `); + await queryRunner.query(`CREATE INDEX "IDX_c8e2abac3a14beb669b1cfa12b" ON "liquidity_management_action" ("onSuccessId") `); + await queryRunner.query(`CREATE INDEX "IDX_a9519dad89f7b8eb7281d64f5b" ON "liquidity_management_action" ("onFailId") `); + await queryRunner.query(`CREATE INDEX "IDX_8952855bd61ae683d3376d2f8b" ON "liquidity_management_rule" ("targetFiatId") `); + await queryRunner.query(`CREATE INDEX "IDX_c45953f23325ad4b4bf1352c57" ON "liquidity_management_rule" ("deficitStartActionId") `); + await queryRunner.query(`CREATE INDEX "IDX_5c1302a8437193bef9610640fc" ON "liquidity_management_rule" ("redundancyStartActionId") `); + await queryRunner.query(`CREATE INDEX "IDX_364aab8734cdeb697f69d0fa2f" ON "asset_price" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_b89a7cbab6c121f5a092815fce" ON "custody_account" ("ownerId") `); + await queryRunner.query(`CREATE INDEX "IDX_45213c9c7521d41be00fa5ead9" ON "custody_account_access" ("accountId") `); + await queryRunner.query(`CREATE INDEX "IDX_8a4612269b283bf40950ddb848" ON "custody_account_access" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_0240361c288231f5c697271961" ON "deposit_route" ("rewardDepositId") `); + await queryRunner.query(`CREATE INDEX "IDX_4dcaef82d41e2edac13836cd60" ON "deposit_route" ("rewardAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_eed4136fa591f383d1079b1902" ON "deposit_route" ("paybackDepositId") `); + await queryRunner.query(`CREATE INDEX "IDX_18d8b5edf0bc3420be7cc8190e" ON "deposit_route" ("paybackAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_6538dff053863dce6b4b8c507f" ON "deposit_route" ("fiatId") `); + await queryRunner.query(`CREATE INDEX "IDX_45e407e37234f3420b8f1d71a5" ON "deposit_route" ("bankDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_39c992b33c4680ea8ad49afb32" ON "deposit_route" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_0a803db97bfc687c23d8c2001e" ON "deposit_route" ("targetDepositId") `); + await queryRunner.query(`CREATE INDEX "IDX_5ac102287f50d730587224283c" ON "payment_activation" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_1968cc8772398abbe1e97b8a94" ON "payment_activation" ("paymentId") `); + await queryRunner.query(`CREATE INDEX "IDX_cc0e305241cc6001264d658ff6" ON "payment_activation" ("quoteId") `); + await queryRunner.query(`CREATE INDEX "IDX_8cad0a41057dc89a8565b5428c" ON "payment_quote" ("paymentId") `); + await queryRunner.query(`CREATE INDEX "IDX_2b3b0fae479b9c6a7b273c06db" ON "support_log" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_2f91b0cacd4211fe1bbe72f1c0" ON "support_log" ("limitRequestId") `); + await queryRunner.query(`CREATE INDEX "IDX_aa91047753c3fc6b97940ac0d1" ON "support_log" ("supportIssueId") `); + await queryRunner.query(`CREATE INDEX "IDX_6bdfc09227eede67ed4779f74d" ON "support_message" ("issueId") `); + await queryRunner.query(`CREATE INDEX "IDX_89d3a139a375bd2dba87094fb6" ON "support_issue" ("transactionId") `); + await queryRunner.query(`CREATE INDEX "IDX_435dd154dd468fac77ba843668" ON "support_issue" ("transactionRequestId") `); + await queryRunner.query(`CREATE INDEX "IDX_740b0ab59ed9cf0d5700f26604" ON "support_issue" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_0bb3e2fdbf16f7920ee4dabd06" ON "transaction_request" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_87abfc63585017ae9e65629c84" ON "custody_order_step" ("orderId") `); + await queryRunner.query(`CREATE INDEX "IDX_67425e623d89efe4ae1a48dbad" ON "custody_order" ("initiatedById") `); + await queryRunner.query(`CREATE INDEX "IDX_1017b402d474e22b86ae7289a4" ON "liquidity_management_order" ("pipelineId") `); + await queryRunner.query(`CREATE INDEX "IDX_2bf0b69330bb42c83d5848b475" ON "liquidity_management_order" ("actionId") `); + await queryRunner.query(`CREATE INDEX "IDX_e147892706eb3dd28e0775ba13" ON "liquidity_management_pipeline" ("currentActionId") `); + await queryRunner.query(`CREATE INDEX "IDX_20d24dc1eaf1c4a9c6a78e6d6a" ON "liquidity_management_pipeline" ("previousActionId") `); + await queryRunner.query(`CREATE INDEX "IDX_8706ada4924baf0b267b0501c8" ON "ref_reward" ("outputAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_d4bb01d7afb4b898d88cf8c136" ON "ref_reward" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_0bdf973ad618dffd7a7c6c53dc" ON "ref_reward" ("liquidityPipelineId") `); + await queryRunner.query(`CREATE INDEX "IDX_a7125bcc9a433258dc395d6c86" ON "bank_tx_return" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_6d1fa9287c2400bd44e7b68271" ON "transaction_risk_assessment" ("transactionId") `); + await queryRunner.query(`CREATE INDEX "IDX_605baeb040ff0fae995404cea3" ON "transaction" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_1e5036f71c59cd6e514280f271" ON "transaction" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_272fc6a981d6fde60688bc4a64" ON "bank_tx_repeat" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_fa54ae64810205dad7e8fee3ea" ON "fiat_output" ("bankId") `); + await queryRunner.query(`CREATE INDEX "IDX_feb41dc8ee54a46b69833ed05b" ON "bank_tx" ("batchId") `); + await queryRunner.query(`CREATE INDEX "IDX_9bf56f7989a7e5717c92221cce" ON "wallet" ("ownerId") `); + await queryRunner.query(`CREATE INDEX "IDX_68a9597d61ec49bff1b41daaee" ON "notification" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_e37c279a7e4fdc3220f39814c5" ON "fee" ("walletId") `); + await queryRunner.query(`CREATE INDEX "IDX_ff542196d21cf9fac32b0ffba8" ON "fee" ("bankId") `); + await queryRunner.query(`CREATE INDEX "IDX_5499b5d0a7e01d2433c6f6c97a" ON "liquidity_order" ("referenceAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_1e75a3f4817c922d85cf3e9be1" ON "liquidity_order" ("targetAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_1a898d3850e8a95e1b7bede19c" ON "liquidity_order" ("swapAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_8c116f65742249f450313610c2" ON "liquidity_order" ("feeAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_5669e232b56be7b85df413b784" ON "buy_fiat" ("fiatOutputId") `); + await queryRunner.query(`CREATE INDEX "IDX_17cdc5fdbc341100fde982dcd2" ON "buy_fiat" ("sellId") `); + await queryRunner.query(`CREATE INDEX "IDX_8c7b5e695c05e78635b8c0c749" ON "buy_fiat" ("bankTxId") `); + await queryRunner.query(`CREATE INDEX "IDX_ac14ac0ce8d0497a88c5065703" ON "buy_fiat" ("bankDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_a1fdc1bf1ba7c0eed9b74727cd" ON "buy_fiat" ("outputReferenceAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_c96a97b5909a60639145b724cd" ON "staking_reward" ("outputAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_6d44460770c83668768ff7c352" ON "staking_reward" ("stakingId") `); + await queryRunner.query(`CREATE INDEX "IDX_3e0f683d5bf0777f30b143db78" ON "crypto_input" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_fd82f69592380d0a2bc557cf0d" ON "crypto_input" ("routeId") `); + await queryRunner.query(`CREATE INDEX "IDX_c236da3e9506bc76cac08832fb" ON "crypto_input" ("paymentLinkPaymentId") `); + await queryRunner.query(`CREATE INDEX "IDX_4a40ddce088ae470c31b72ac18" ON "crypto_input" ("paymentQuoteId") `); + await queryRunner.query(`CREATE INDEX "IDX_d1f710811ec3f2352799bea96d" ON "payment_link_payment" ("currencyId") `); + await queryRunner.query(`CREATE INDEX "IDX_4585705bcdfb4cdcfd66c86881" ON "payment_link" ("routeId") `); + await queryRunner.query(`CREATE INDEX "IDX_15baf13321ac4e342a756fe015" ON "bank_data" ("preferredCurrencyId") `); + await queryRunner.query(`CREATE INDEX "IDX_faf8d8f795f788cac5aa079b2f" ON "bank_data" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_5efe36a1cf182e40c0f2e34bb7" ON "buy_crypto_fee" ("feeReferenceAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_00e1e81f9595e9f65f6c920459" ON "buy_crypto" ("buyId") `); + await queryRunner.query(`CREATE INDEX "IDX_8de69d901e2d2949e23d550c01" ON "buy_crypto" ("cryptoRouteId") `); + await queryRunner.query(`CREATE INDEX "IDX_19bb6514f0c92a4088dcbf6617" ON "buy_crypto" ("batchId") `); + await queryRunner.query(`CREATE INDEX "IDX_73b6d9b1037a714d3314e03881" ON "buy" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_ae4cd183a5bb4265a3395af35c" ON "buy" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_ce6a9309b2dac5acbc26f8eadb" ON "buy" ("depositId") `); + await queryRunner.query(`CREATE INDEX "IDX_12039297cf2fb30625f423f548" ON "custody_balance" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_235417a8c4f430e453eae06379" ON "custody_balance" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_b141d5e0d74c87aef92eae2847" ON "custody_balance" ("accountId") `); + await queryRunner.query(`CREATE INDEX "IDX_6ac4ef2ce62d9892fff37f6462" ON "staking_ref_reward" ("outputAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_fc57074ad97e10f40122b195d3" ON "staking_ref_reward" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_11a71eb4da3a8bbbc1fd98f0e0" ON "staking_ref_reward" ("stakingId") `); + await queryRunner.query(`CREATE INDEX "IDX_922e8c1d396025973ec81e2a40" ON "user" ("walletId") `); + await queryRunner.query(`CREATE INDEX "IDX_316fdc0ecba8febcd28417fe54" ON "user" ("custodyProviderId") `); + await queryRunner.query(`CREATE INDEX "IDX_22abf72351fb3a0c9cd84d88bb" ON "user" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_3d123a28635558f206e57fc908" ON "user" ("primaryUserId") `); + await queryRunner.query(`CREATE INDEX "IDX_20e823fee19baff0c5090ab72d" ON "user" ("refAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_bf8ce326ec41adc02940bccf91" ON "user" ("custodyAccountId") `); + await queryRunner.query(`CREATE INDEX "IDX_570c4af000f351d30d338636ea" ON "faucet_request" ("assetId") `); + await queryRunner.query(`CREATE INDEX "IDX_c0f4196ecce9a6dfe6f41e3c15" ON "faucet_request" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_e1b7f08a82b3c6b369c6f173b4" ON "faucet_request" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_73df258b5010de85f1869d2991" ON "kyc_log" ("fileId") `); + await queryRunner.query(`CREATE INDEX "IDX_3d1856c90a8b4b20625ce8719e" ON "kyc_log" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_0b0568192de90bc31d61a3cf36" ON "kyc_log" ("kycStepId") `); + await queryRunner.query(`CREATE INDEX "IDX_c6404de74ee43d27c87050939d" ON "kyc_log" ("bankDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_b26c58cd335e7911fa7935a6f1" ON "recommendation" ("recommenderId") `); + await queryRunner.query(`CREATE INDEX "IDX_9e74ac8f02e38e78907e79ba01" ON "recommendation" ("recommendedId") `); + await queryRunner.query(`CREATE INDEX "IDX_04c352bfacb76b730b9e21c5e8" ON "kyc_step" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_a34b22e4385a7cac26e16ab89e" ON "kyc_file" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_da534c346667b71a9b4aecb845" ON "kyc_file" ("kycStepId") `); + await queryRunner.query(`CREATE INDEX "IDX_3c6b96df57028f34f8634f839a" ON "virtual_iban" ("currencyId") `); + await queryRunner.query(`CREATE INDEX "IDX_120a2739b632dc95c854f6b947" ON "virtual_iban" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_708b5ca3b87711bf3052dd39ce" ON "virtual_iban" ("bankId") `); + await queryRunner.query(`CREATE INDEX "IDX_a706f77e40a7e9fb2f745d1fb7" ON "virtual_iban" ("buyId") `); + await queryRunner.query(`CREATE INDEX "IDX_a8300a9cc86e506ebe73fed789" ON "organization" ("accountOpenerId") `); + await queryRunner.query(`CREATE INDEX "IDX_96b784c2e08bc1ee69fc1e3c2a" ON "organization" ("countryId") `); + await queryRunner.query(`CREATE INDEX "IDX_56f39477fa929bd1a8c93ad66d" ON "user_data_relation" ("accountId") `); + await queryRunner.query(`CREATE INDEX "IDX_02a41115677a4916bb523c427d" ON "user_data_relation" ("relatedAccountId") `); + await queryRunner.query(`CREATE INDEX "IDX_01cbff97f07b85e56ff246088c" ON "user_data" ("verifiedCountryId") `); + await queryRunner.query(`CREATE INDEX "IDX_07524cd9a17d5d9aba78c93a35" ON "user_data" ("countryId") `); + await queryRunner.query(`CREATE INDEX "IDX_89c1ece4cd00924230fc0b92c5" ON "user_data" ("nationalityId") `); + await queryRunner.query(`CREATE INDEX "IDX_fd9f1c6157c0cafaa6557c0523" ON "user_data" ("organizationCountryId") `); + await queryRunner.query(`CREATE INDEX "IDX_2e6642ec09da8e0da57dfed338" ON "user_data" ("languageId") `); + await queryRunner.query(`CREATE INDEX "IDX_03359a6602ce5796029a29f119" ON "user_data" ("currencyId") `); + await queryRunner.query(`CREATE INDEX "IDX_dcf41efbd8bd1f2a80f369028b" ON "user_data" ("walletId") `); + await queryRunner.query(`CREATE INDEX "IDX_8f119df333e0f6a70aac06f0d4" ON "user_data" ("accountOpenerId") `); + await queryRunner.query(`CREATE INDEX "IDX_692d0b671f0e36d1b8cfe62549" ON "user_data" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_8efce822823d601f342809a5f5" ON "ip_log" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_b91fc10a7418de64ff2b0b2d2c" ON "ip_log" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_31c84229965f595a7e64557f0c" ON "recall" ("bankTxId") `); + await queryRunner.query(`CREATE INDEX "IDX_12996e79d6611144548c364d5b" ON "recall" ("checkoutTxId") `); + await queryRunner.query(`CREATE INDEX "IDX_9d9db094ddf6a60b57431f39e8" ON "recall" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_021227644566f36c31912257a3" ON "mros" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_f272c8c8805969e6a6449c77b3" ON "webhook" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_4112043e14655476ecbc247959" ON "webhook" ("userDataId") `); + await queryRunner.query(`CREATE INDEX "IDX_ac42e3c9f043be4b94fc55c3c8" ON "webhook" ("walletId") `); + await queryRunner.query(`CREATE INDEX "IDX_8d2e2ba466e4a9812dc72a27e9" ON "account_merge" ("masterId") `); + await queryRunner.query(`CREATE INDEX "IDX_978a25a7218bbdb0122b8a0668" ON "account_merge" ("slaveId") `); + await queryRunner.query(`CREATE INDEX "IDX_182ba779e56cf5e1c2db258b78" ON "trading_rule" ("leftAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_8b9f4655138aacdcdefa85f948" ON "trading_rule" ("rightAssetId") `); + await queryRunner.query(`CREATE INDEX "IDX_f862025cb7ca5a2d66d14fb89a" ON "trading_order" ("tradingRuleId") `); + await queryRunner.query(`CREATE INDEX "IDX_a01e680fa2dd6cc0ef3e2bf562" ON "trading_order" ("assetInId") `); + await queryRunner.query(`CREATE INDEX "IDX_b5d03233e434d71b6996838da2" ON "trading_order" ("assetOutId") `); + await queryRunner.query(`CREATE INDEX "IDX_67d87d80c7fef95e846abc85d1" ON "crypto_staking" ("paybackDepositId") `); + await queryRunner.query(`CREATE INDEX "IDX_8e7533a8e8b59c5fd10742033d" ON "crypto_staking" ("stakingRouteId") `); + await queryRunner.query(`CREATE INDEX "IDX_980c76801f97ea9f89f0593cbe" ON "payment_merchant" ("userId") `); + } + + /** + * @param {QueryRunner} queryRunner + */ + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_980c76801f97ea9f89f0593cbe"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8e7533a8e8b59c5fd10742033d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_67d87d80c7fef95e846abc85d1"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b5d03233e434d71b6996838da2"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a01e680fa2dd6cc0ef3e2bf562"`); + await queryRunner.query(`DROP INDEX "public"."IDX_f862025cb7ca5a2d66d14fb89a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8b9f4655138aacdcdefa85f948"`); + await queryRunner.query(`DROP INDEX "public"."IDX_182ba779e56cf5e1c2db258b78"`); + await queryRunner.query(`DROP INDEX "public"."IDX_978a25a7218bbdb0122b8a0668"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8d2e2ba466e4a9812dc72a27e9"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ac42e3c9f043be4b94fc55c3c8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_4112043e14655476ecbc247959"`); + await queryRunner.query(`DROP INDEX "public"."IDX_f272c8c8805969e6a6449c77b3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_021227644566f36c31912257a3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_9d9db094ddf6a60b57431f39e8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_12996e79d6611144548c364d5b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_31c84229965f595a7e64557f0c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b91fc10a7418de64ff2b0b2d2c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8efce822823d601f342809a5f5"`); + await queryRunner.query(`DROP INDEX "public"."IDX_692d0b671f0e36d1b8cfe62549"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8f119df333e0f6a70aac06f0d4"`); + await queryRunner.query(`DROP INDEX "public"."IDX_dcf41efbd8bd1f2a80f369028b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_03359a6602ce5796029a29f119"`); + await queryRunner.query(`DROP INDEX "public"."IDX_2e6642ec09da8e0da57dfed338"`); + await queryRunner.query(`DROP INDEX "public"."IDX_fd9f1c6157c0cafaa6557c0523"`); + await queryRunner.query(`DROP INDEX "public"."IDX_89c1ece4cd00924230fc0b92c5"`); + await queryRunner.query(`DROP INDEX "public"."IDX_07524cd9a17d5d9aba78c93a35"`); + await queryRunner.query(`DROP INDEX "public"."IDX_01cbff97f07b85e56ff246088c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_02a41115677a4916bb523c427d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_56f39477fa929bd1a8c93ad66d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_96b784c2e08bc1ee69fc1e3c2a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a8300a9cc86e506ebe73fed789"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a706f77e40a7e9fb2f745d1fb7"`); + await queryRunner.query(`DROP INDEX "public"."IDX_708b5ca3b87711bf3052dd39ce"`); + await queryRunner.query(`DROP INDEX "public"."IDX_120a2739b632dc95c854f6b947"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3c6b96df57028f34f8634f839a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_da534c346667b71a9b4aecb845"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a34b22e4385a7cac26e16ab89e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_04c352bfacb76b730b9e21c5e8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_9e74ac8f02e38e78907e79ba01"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b26c58cd335e7911fa7935a6f1"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c6404de74ee43d27c87050939d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0b0568192de90bc31d61a3cf36"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3d1856c90a8b4b20625ce8719e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_73df258b5010de85f1869d2991"`); + await queryRunner.query(`DROP INDEX "public"."IDX_e1b7f08a82b3c6b369c6f173b4"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c0f4196ecce9a6dfe6f41e3c15"`); + await queryRunner.query(`DROP INDEX "public"."IDX_570c4af000f351d30d338636ea"`); + await queryRunner.query(`DROP INDEX "public"."IDX_bf8ce326ec41adc02940bccf91"`); + await queryRunner.query(`DROP INDEX "public"."IDX_20e823fee19baff0c5090ab72d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3d123a28635558f206e57fc908"`); + await queryRunner.query(`DROP INDEX "public"."IDX_22abf72351fb3a0c9cd84d88bb"`); + await queryRunner.query(`DROP INDEX "public"."IDX_316fdc0ecba8febcd28417fe54"`); + await queryRunner.query(`DROP INDEX "public"."IDX_922e8c1d396025973ec81e2a40"`); + await queryRunner.query(`DROP INDEX "public"."IDX_11a71eb4da3a8bbbc1fd98f0e0"`); + await queryRunner.query(`DROP INDEX "public"."IDX_fc57074ad97e10f40122b195d3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_6ac4ef2ce62d9892fff37f6462"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b141d5e0d74c87aef92eae2847"`); + await queryRunner.query(`DROP INDEX "public"."IDX_235417a8c4f430e453eae06379"`); + await queryRunner.query(`DROP INDEX "public"."IDX_12039297cf2fb30625f423f548"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ce6a9309b2dac5acbc26f8eadb"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ae4cd183a5bb4265a3395af35c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_73b6d9b1037a714d3314e03881"`); + await queryRunner.query(`DROP INDEX "public"."IDX_19bb6514f0c92a4088dcbf6617"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8de69d901e2d2949e23d550c01"`); + await queryRunner.query(`DROP INDEX "public"."IDX_00e1e81f9595e9f65f6c920459"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5efe36a1cf182e40c0f2e34bb7"`); + await queryRunner.query(`DROP INDEX "public"."IDX_faf8d8f795f788cac5aa079b2f"`); + await queryRunner.query(`DROP INDEX "public"."IDX_15baf13321ac4e342a756fe015"`); + await queryRunner.query(`DROP INDEX "public"."IDX_4585705bcdfb4cdcfd66c86881"`); + await queryRunner.query(`DROP INDEX "public"."IDX_d1f710811ec3f2352799bea96d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_4a40ddce088ae470c31b72ac18"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c236da3e9506bc76cac08832fb"`); + await queryRunner.query(`DROP INDEX "public"."IDX_fd82f69592380d0a2bc557cf0d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3e0f683d5bf0777f30b143db78"`); + await queryRunner.query(`DROP INDEX "public"."IDX_6d44460770c83668768ff7c352"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c96a97b5909a60639145b724cd"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a1fdc1bf1ba7c0eed9b74727cd"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ac14ac0ce8d0497a88c5065703"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8c7b5e695c05e78635b8c0c749"`); + await queryRunner.query(`DROP INDEX "public"."IDX_17cdc5fdbc341100fde982dcd2"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5669e232b56be7b85df413b784"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8c116f65742249f450313610c2"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1a898d3850e8a95e1b7bede19c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1e75a3f4817c922d85cf3e9be1"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5499b5d0a7e01d2433c6f6c97a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ff542196d21cf9fac32b0ffba8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_e37c279a7e4fdc3220f39814c5"`); + await queryRunner.query(`DROP INDEX "public"."IDX_68a9597d61ec49bff1b41daaee"`); + await queryRunner.query(`DROP INDEX "public"."IDX_9bf56f7989a7e5717c92221cce"`); + await queryRunner.query(`DROP INDEX "public"."IDX_feb41dc8ee54a46b69833ed05b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_fa54ae64810205dad7e8fee3ea"`); + await queryRunner.query(`DROP INDEX "public"."IDX_272fc6a981d6fde60688bc4a64"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1e5036f71c59cd6e514280f271"`); + await queryRunner.query(`DROP INDEX "public"."IDX_605baeb040ff0fae995404cea3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_6d1fa9287c2400bd44e7b68271"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a7125bcc9a433258dc395d6c86"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0bdf973ad618dffd7a7c6c53dc"`); + await queryRunner.query(`DROP INDEX "public"."IDX_d4bb01d7afb4b898d88cf8c136"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8706ada4924baf0b267b0501c8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_20d24dc1eaf1c4a9c6a78e6d6a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_e147892706eb3dd28e0775ba13"`); + await queryRunner.query(`DROP INDEX "public"."IDX_2bf0b69330bb42c83d5848b475"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1017b402d474e22b86ae7289a4"`); + await queryRunner.query(`DROP INDEX "public"."IDX_67425e623d89efe4ae1a48dbad"`); + await queryRunner.query(`DROP INDEX "public"."IDX_87abfc63585017ae9e65629c84"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0bb3e2fdbf16f7920ee4dabd06"`); + await queryRunner.query(`DROP INDEX "public"."IDX_740b0ab59ed9cf0d5700f26604"`); + await queryRunner.query(`DROP INDEX "public"."IDX_435dd154dd468fac77ba843668"`); + await queryRunner.query(`DROP INDEX "public"."IDX_89d3a139a375bd2dba87094fb6"`); + await queryRunner.query(`DROP INDEX "public"."IDX_6bdfc09227eede67ed4779f74d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_aa91047753c3fc6b97940ac0d1"`); + await queryRunner.query(`DROP INDEX "public"."IDX_2f91b0cacd4211fe1bbe72f1c0"`); + await queryRunner.query(`DROP INDEX "public"."IDX_2b3b0fae479b9c6a7b273c06db"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8cad0a41057dc89a8565b5428c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_cc0e305241cc6001264d658ff6"`); + await queryRunner.query(`DROP INDEX "public"."IDX_1968cc8772398abbe1e97b8a94"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5ac102287f50d730587224283c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0a803db97bfc687c23d8c2001e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_39c992b33c4680ea8ad49afb32"`); + await queryRunner.query(`DROP INDEX "public"."IDX_45e407e37234f3420b8f1d71a5"`); + await queryRunner.query(`DROP INDEX "public"."IDX_6538dff053863dce6b4b8c507f"`); + await queryRunner.query(`DROP INDEX "public"."IDX_18d8b5edf0bc3420be7cc8190e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_eed4136fa591f383d1079b1902"`); + await queryRunner.query(`DROP INDEX "public"."IDX_4dcaef82d41e2edac13836cd60"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0240361c288231f5c697271961"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8a4612269b283bf40950ddb848"`); + await queryRunner.query(`DROP INDEX "public"."IDX_45213c9c7521d41be00fa5ead9"`); + await queryRunner.query(`DROP INDEX "public"."IDX_b89a7cbab6c121f5a092815fce"`); + await queryRunner.query(`DROP INDEX "public"."IDX_364aab8734cdeb697f69d0fa2f"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5c1302a8437193bef9610640fc"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c45953f23325ad4b4bf1352c57"`); + await queryRunner.query(`DROP INDEX "public"."IDX_8952855bd61ae683d3376d2f8b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a9519dad89f7b8eb7281d64f5b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c8e2abac3a14beb669b1cfa12b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_498338cbab828a1938e283a16d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_85d63658ee8348a72cc5704f9f"`); + } +} diff --git a/src/shared/models/fiat/fiat.entity.ts b/src/shared/models/fiat/fiat.entity.ts index f2775b931f..a0a440f86a 100644 --- a/src/shared/models/fiat/fiat.entity.ts +++ b/src/shared/models/fiat/fiat.entity.ts @@ -1,6 +1,6 @@ import { AmlRule } from 'src/subdomains/core/aml/enums/aml-rule.enum'; import { PriceRule } from 'src/subdomains/supporting/pricing/domain/entities/price-rule.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { IEntity } from '../entity'; export interface IbanCountryConfig { @@ -34,6 +34,7 @@ export class Fiat extends IEntity { @Column({ default: true }) refundEnabled: boolean; + @Index() @ManyToOne(() => PriceRule) priceRule: PriceRule; diff --git a/src/shared/models/ip-log/ip-log.entity.ts b/src/shared/models/ip-log/ip-log.entity.ts index 01f01bc60d..cb322554f7 100644 --- a/src/shared/models/ip-log/ip-log.entity.ts +++ b/src/shared/models/ip-log/ip-log.entity.ts @@ -2,7 +2,7 @@ import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { WalletType } from 'src/subdomains/generic/user/models/user/user.enum'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; @Entity() export class IpLog extends IEntity { @@ -24,9 +24,11 @@ export class IpLog extends IEntity { @Column({ length: 256, nullable: true }) walletType?: WalletType; + @Index() @ManyToOne(() => User, { nullable: true }) user?: User; + @Index() @ManyToOne(() => UserData, { nullable: true }) userData?: UserData; } diff --git a/src/shared/models/reward.entity.ts b/src/shared/models/reward.entity.ts index 32671ea014..0b80e49455 100644 --- a/src/shared/models/reward.entity.ts +++ b/src/shared/models/reward.entity.ts @@ -1,5 +1,5 @@ import { IEntity } from 'src/shared/models/entity'; -import { Column, ManyToOne } from 'typeorm'; +import { Column, Index, ManyToOne } from 'typeorm'; import { Asset } from './asset/asset.entity'; export class Reward extends IEntity { @@ -24,6 +24,7 @@ export class Reward extends IEntity { @Column({ type: 'float', nullable: true }) outputAmount?: number; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) outputAsset?: Asset; diff --git a/src/subdomains/core/buy-crypto/process/entities/buy-crypto-fees.entity.ts b/src/subdomains/core/buy-crypto/process/entities/buy-crypto-fees.entity.ts index 987a0de41a..6cac3c895a 100644 --- a/src/subdomains/core/buy-crypto/process/entities/buy-crypto-fees.entity.ts +++ b/src/subdomains/core/buy-crypto/process/entities/buy-crypto-fees.entity.ts @@ -1,7 +1,7 @@ import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { Util } from 'src/shared/utils/util'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { BuyCrypto } from './buy-crypto.entity'; @Entity() @@ -10,6 +10,7 @@ export class BuyCryptoFee extends IEntity { @JoinColumn() buyCrypto: BuyCrypto; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: false }) feeReferenceAsset: Asset; diff --git a/src/subdomains/core/buy-crypto/process/entities/buy-crypto.entity.ts b/src/subdomains/core/buy-crypto/process/entities/buy-crypto.entity.ts index 550840090a..dbe70ad41f 100644 --- a/src/subdomains/core/buy-crypto/process/entities/buy-crypto.entity.ts +++ b/src/subdomains/core/buy-crypto/process/entities/buy-crypto.entity.ts @@ -36,7 +36,7 @@ import { SpecialExternalAccount } from 'src/subdomains/supporting/payment/entiti import { Transaction } from 'src/subdomains/supporting/payment/entities/transaction.entity'; import { Price, PriceStep } from 'src/subdomains/supporting/pricing/domain/entities/price'; import { PriceCurrency } from 'src/subdomains/supporting/pricing/services/pricing.service'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { AmlReason } from '../../../aml/enums/aml-reason.enum'; import { CheckStatus } from '../../../aml/enums/check-status.enum'; import { Buy } from '../../routes/buy/buy.entity'; @@ -78,6 +78,7 @@ export class BuyCrypto extends IEntity { @JoinColumn() checkoutTx?: CheckoutTx; + @Index() @ManyToOne(() => Buy, (buy) => buy.buyCryptos, { nullable: true }) buy?: Buy; @@ -85,9 +86,11 @@ export class BuyCrypto extends IEntity { @JoinColumn() cryptoInput?: CryptoInput; + @Index() @ManyToOne(() => Swap, (cryptoRoute) => cryptoRoute.buyCryptos, { nullable: true }) cryptoRoute?: Swap; + @Index() @ManyToOne(() => BuyCryptoBatch, (batch) => batch.transactions, { eager: true, nullable: true }) batch?: BuyCryptoBatch; diff --git a/src/subdomains/core/buy-crypto/routes/buy/buy.entity.ts b/src/subdomains/core/buy-crypto/routes/buy/buy.entity.ts index 8a90513964..5a8eb12290 100644 --- a/src/subdomains/core/buy-crypto/routes/buy/buy.entity.ts +++ b/src/subdomains/core/buy-crypto/routes/buy/buy.entity.ts @@ -28,12 +28,15 @@ export class Buy extends IEntity { @Column({ default: true }) active: boolean; + @Index() @ManyToOne(() => User, (user) => user.buys) user: User; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) asset?: Asset; + @Index() @ManyToOne(() => Deposit, { eager: true, nullable: true }) deposit?: Deposit; diff --git a/src/subdomains/core/buy-crypto/routes/swap/swap.entity.ts b/src/subdomains/core/buy-crypto/routes/swap/swap.entity.ts index 4229f6995b..f61091d9e6 100644 --- a/src/subdomains/core/buy-crypto/routes/swap/swap.entity.ts +++ b/src/subdomains/core/buy-crypto/routes/swap/swap.entity.ts @@ -5,7 +5,7 @@ import { PaymentLink } from 'src/subdomains/core/payment-link/entities/payment-l import { Route } from 'src/subdomains/core/route/route.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { CryptoInput } from 'src/subdomains/supporting/payin/entities/crypto-input.entity'; -import { ChildEntity, Column, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { ChildEntity, Column, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { Deposit } from '../../../../supporting/address-pool/deposit/deposit.entity'; import { DepositRoute, RouteType } from '../../../../supporting/address-pool/route/deposit-route.entity'; @@ -22,9 +22,11 @@ export class Swap extends DepositRoute { @ManyToOne(() => User, (user) => user.swaps, { nullable: false }) declare user: User; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) asset?: Asset; + @Index() @ManyToOne(() => Deposit, { eager: true, nullable: true }) targetDeposit?: Deposit; diff --git a/src/subdomains/core/custody/entities/custody-account-access.entity.ts b/src/subdomains/core/custody/entities/custody-account-access.entity.ts index 4652bdcebd..63b912e051 100644 --- a/src/subdomains/core/custody/entities/custody-account-access.entity.ts +++ b/src/subdomains/core/custody/entities/custody-account-access.entity.ts @@ -7,9 +7,11 @@ import { CustodyAccount } from './custody-account.entity'; @Entity() @Index((a: CustodyAccountAccess) => [a.account, a.userData], { unique: true }) export class CustodyAccountAccess extends IEntity { + @Index() @ManyToOne(() => CustodyAccount, (custodyAccount) => custodyAccount.accessGrants, { nullable: false }) account: CustodyAccount; + @Index() @ManyToOne(() => UserData, { nullable: false }) userData: UserData; diff --git a/src/subdomains/core/custody/entities/custody-account.entity.ts b/src/subdomains/core/custody/entities/custody-account.entity.ts index 7a6dc57dd5..5d20057f62 100644 --- a/src/subdomains/core/custody/entities/custody-account.entity.ts +++ b/src/subdomains/core/custody/entities/custody-account.entity.ts @@ -1,6 +1,6 @@ import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; -import { Column, Entity, ManyToOne, OneToMany } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, OneToMany } from 'typeorm'; import { CustodyAccountStatus } from '../enums/custody'; import { CustodyAccountAccess } from './custody-account-access.entity'; @@ -12,6 +12,7 @@ export class CustodyAccount extends IEntity { @Column({ type: 'text', nullable: true }) description?: string; + @Index() @ManyToOne(() => UserData, { nullable: false }) owner: UserData; diff --git a/src/subdomains/core/custody/entities/custody-balance.entity.ts b/src/subdomains/core/custody/entities/custody-balance.entity.ts index 55f6540123..55e2025f20 100644 --- a/src/subdomains/core/custody/entities/custody-balance.entity.ts +++ b/src/subdomains/core/custody/entities/custody-balance.entity.ts @@ -10,12 +10,15 @@ export class CustodyBalance extends IEntity { @Column({ type: 'float', default: 0 }) balance: number; + @Index() @ManyToOne(() => User, (user) => user.custodyBalances, { nullable: false, eager: true }) user: User; + @Index() @ManyToOne(() => Asset, { nullable: false, eager: true }) asset: Asset; + @Index() @ManyToOne(() => CustodyAccount, { nullable: true }) account?: CustodyAccount; } diff --git a/src/subdomains/core/custody/entities/custody-order-step.entity.ts b/src/subdomains/core/custody/entities/custody-order-step.entity.ts index f0ee12bc9d..09e0e08388 100644 --- a/src/subdomains/core/custody/entities/custody-order-step.entity.ts +++ b/src/subdomains/core/custody/entities/custody-order-step.entity.ts @@ -1,11 +1,12 @@ import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { Util } from 'src/shared/utils/util'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { CustodyOrderStepCommand, CustodyOrderStepContext, CustodyOrderStepStatus } from '../enums/custody'; import { CustodyOrder } from './custody-order.entity'; @Entity() export class CustodyOrderStep extends IEntity { + @Index() @ManyToOne(() => CustodyOrder, (order) => order.steps, { nullable: false, eager: true }) order: CustodyOrder; diff --git a/src/subdomains/core/custody/entities/custody-order.entity.ts b/src/subdomains/core/custody/entities/custody-order.entity.ts index 8fa0099b6a..14983e0893 100644 --- a/src/subdomains/core/custody/entities/custody-order.entity.ts +++ b/src/subdomains/core/custody/entities/custody-order.entity.ts @@ -5,7 +5,7 @@ import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { TransactionRequest } from 'src/subdomains/supporting/payment/entities/transaction-request.entity'; import { Transaction } from 'src/subdomains/supporting/payment/entities/transaction.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { Buy } from '../../buy-crypto/routes/buy/buy.entity'; import { Swap } from '../../buy-crypto/routes/swap/swap.entity'; import { Sell } from '../../sell-crypto/route/sell.entity'; @@ -42,6 +42,7 @@ export class CustodyOrder extends IEntity { @ManyToOne(() => CustodyAccount, { nullable: true }) account?: CustodyAccount; + @Index() @ManyToOne(() => UserData, { nullable: true }) initiatedBy?: UserData; diff --git a/src/subdomains/core/faucet-request/entities/faucet-request.entity.ts b/src/subdomains/core/faucet-request/entities/faucet-request.entity.ts index 7fc16e81a2..502cd093b2 100644 --- a/src/subdomains/core/faucet-request/entities/faucet-request.entity.ts +++ b/src/subdomains/core/faucet-request/entities/faucet-request.entity.ts @@ -2,7 +2,7 @@ import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { FaucetRequestStatus } from '../enums/faucet-request'; @Entity() @@ -13,12 +13,15 @@ export class FaucetRequest extends IEntity { @Column({ type: 'float' }) amount: number; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: false }) asset: Asset; + @Index() @ManyToOne(() => UserData, (userData) => userData.faucetRequests, { nullable: false }) userData: UserData; + @Index() @ManyToOne(() => User, { nullable: false }) user: User; diff --git a/src/subdomains/core/liquidity-management/entities/liquidity-management-action.entity.ts b/src/subdomains/core/liquidity-management/entities/liquidity-management-action.entity.ts index 2e27e6e438..0743ef20bf 100644 --- a/src/subdomains/core/liquidity-management/entities/liquidity-management-action.entity.ts +++ b/src/subdomains/core/liquidity-management/entities/liquidity-management-action.entity.ts @@ -1,5 +1,5 @@ import { IEntity } from 'src/shared/models/entity'; -import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm'; import { LiquidityManagementSystem } from '../enums'; @Entity() @@ -16,10 +16,12 @@ export class LiquidityManagementAction extends IEntity { @Column({ type: 'text', nullable: true }) params?: string; + @Index() @ManyToOne(() => LiquidityManagementAction, { nullable: true }) @JoinColumn() onSuccess?: LiquidityManagementAction | null; + @Index() @ManyToOne(() => LiquidityManagementAction, { nullable: true }) @JoinColumn() onFail?: LiquidityManagementAction | null; diff --git a/src/subdomains/core/liquidity-management/entities/liquidity-management-order.entity.ts b/src/subdomains/core/liquidity-management/entities/liquidity-management-order.entity.ts index 6031a451ab..a2569b648c 100644 --- a/src/subdomains/core/liquidity-management/entities/liquidity-management-order.entity.ts +++ b/src/subdomains/core/liquidity-management/entities/liquidity-management-order.entity.ts @@ -1,7 +1,7 @@ import { Active } from 'src/shared/models/active'; import { IEntity } from 'src/shared/models/entity'; import { Price, PriceStep } from 'src/subdomains/supporting/pricing/domain/entities/price'; -import { Column, Entity, JoinTable, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, JoinTable, ManyToOne } from 'typeorm'; import { LiquidityManagementOrderStatus } from '../enums'; import { OrderFailedException } from '../exceptions/order-failed.exception'; import { OrderNotProcessableException } from '../exceptions/order-not-processable.exception'; @@ -31,6 +31,7 @@ export class LiquidityManagementOrder extends IEntity { @Column({ length: 256, nullable: true }) outputAsset?: string; + @Index() @ManyToOne(() => LiquidityManagementPipeline, (liquidityPipeline) => liquidityPipeline.buyCryptos, { eager: true, nullable: false, @@ -38,6 +39,7 @@ export class LiquidityManagementOrder extends IEntity { @JoinTable() pipeline: LiquidityManagementPipeline; + @Index() @ManyToOne(() => LiquidityManagementAction, { eager: true, nullable: false }) @JoinTable() action: LiquidityManagementAction; diff --git a/src/subdomains/core/liquidity-management/entities/liquidity-management-pipeline.entity.ts b/src/subdomains/core/liquidity-management/entities/liquidity-management-pipeline.entity.ts index f34a5da967..aa2d78cd99 100644 --- a/src/subdomains/core/liquidity-management/entities/liquidity-management-pipeline.entity.ts +++ b/src/subdomains/core/liquidity-management/entities/liquidity-management-pipeline.entity.ts @@ -44,10 +44,12 @@ export class LiquidityManagementPipeline extends IEntity { @Column({ type: 'float', nullable: true }) maxAmount?: number; + @Index() @ManyToOne(() => LiquidityManagementAction, { eager: true, nullable: true }) @JoinTable() currentAction?: LiquidityManagementAction; + @Index() @ManyToOne(() => LiquidityManagementAction, { eager: true, nullable: true }) @JoinTable() previousAction?: LiquidityManagementAction; diff --git a/src/subdomains/core/liquidity-management/entities/liquidity-management-rule.entity.ts b/src/subdomains/core/liquidity-management/entities/liquidity-management-rule.entity.ts index 8284736e5e..cac6c33eb3 100644 --- a/src/subdomains/core/liquidity-management/entities/liquidity-management-rule.entity.ts +++ b/src/subdomains/core/liquidity-management/entities/liquidity-management-rule.entity.ts @@ -23,6 +23,7 @@ export class LiquidityManagementRule extends IEntity { @JoinColumn() targetAsset?: Asset; + @Index() @ManyToOne(() => Fiat, { eager: true, nullable: true }) targetFiat?: Fiat; @@ -38,9 +39,11 @@ export class LiquidityManagementRule extends IEntity { @Column({ type: 'float', nullable: true }) limit?: number; + @Index() @ManyToOne(() => LiquidityManagementAction, { eager: true, nullable: true }) deficitStartAction?: LiquidityManagementAction; + @Index() @ManyToOne(() => LiquidityManagementAction, { eager: true, nullable: true }) redundancyStartAction?: LiquidityManagementAction; diff --git a/src/subdomains/core/payment-link/entities/payment-activation.entity.ts b/src/subdomains/core/payment-link/entities/payment-activation.entity.ts index 80b7427ac4..3feff9148e 100644 --- a/src/subdomains/core/payment-link/entities/payment-activation.entity.ts +++ b/src/subdomains/core/payment-link/entities/payment-activation.entity.ts @@ -18,6 +18,7 @@ export class PaymentActivation extends IEntity { @Column() method: TransferMethod; + @Index() @ManyToOne(() => Asset, { nullable: false, eager: true }) asset: Asset; @@ -36,9 +37,11 @@ export class PaymentActivation extends IEntity { @Column({ length: 256 }) standard: PaymentStandard; + @Index() @ManyToOne(() => PaymentLinkPayment, (p) => p.activations, { nullable: false }) payment: PaymentLinkPayment; + @Index() @ManyToOne(() => PaymentQuote, (q) => q.activations, { nullable: true }) quote?: PaymentQuote; } diff --git a/src/subdomains/core/payment-link/entities/payment-link-payment.entity.ts b/src/subdomains/core/payment-link/entities/payment-link-payment.entity.ts index 9caa13e2b6..c16fe33ebb 100644 --- a/src/subdomains/core/payment-link/entities/payment-link-payment.entity.ts +++ b/src/subdomains/core/payment-link/entities/payment-link-payment.entity.ts @@ -33,6 +33,7 @@ export class PaymentLinkPayment extends IEntity { @Column({ type: 'float' }) amount: number; + @Index() @ManyToOne(() => Fiat, { nullable: false, eager: true }) currency: Fiat; diff --git a/src/subdomains/core/payment-link/entities/payment-link.entity.ts b/src/subdomains/core/payment-link/entities/payment-link.entity.ts index d203a7a627..8fc4990a77 100644 --- a/src/subdomains/core/payment-link/entities/payment-link.entity.ts +++ b/src/subdomains/core/payment-link/entities/payment-link.entity.ts @@ -2,7 +2,7 @@ import { merge } from 'lodash'; import { IEntity } from 'src/shared/models/entity'; import { Util } from 'src/shared/utils/util'; import { DepositRoute } from 'src/subdomains/supporting/address-pool/route/deposit-route.entity'; -import { Column, Entity, ManyToOne, OneToMany } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, OneToMany } from 'typeorm'; import { PaymentLinkRecipientDto } from '../dto/payment-link-recipient.dto'; import { PaymentLinkMode, PaymentLinkPaymentStatus, PaymentLinkStatus, PaymentStandard } from '../enums'; import { PaymentLinkPayment } from './payment-link-payment.entity'; @@ -13,6 +13,7 @@ export class PaymentLink extends IEntity { @OneToMany(() => PaymentLinkPayment, (payment) => payment.link, { nullable: true }) payments?: PaymentLinkPayment[]; + @Index() @ManyToOne(() => DepositRoute, { nullable: false }) route: DepositRoute; diff --git a/src/subdomains/core/payment-link/entities/payment-merchant.entity.ts b/src/subdomains/core/payment-link/entities/payment-merchant.entity.ts index 816ba1e13e..49127bf083 100644 --- a/src/subdomains/core/payment-link/entities/payment-merchant.entity.ts +++ b/src/subdomains/core/payment-link/entities/payment-merchant.entity.ts @@ -1,6 +1,6 @@ import { IEntity } from 'src/shared/models/entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { PaymentMerchantStatus } from '../enums'; @Entity() @@ -14,6 +14,7 @@ export class PaymentMerchant extends IEntity { @Column({ type: 'text' }) data: string; + @Index() @ManyToOne(() => User, { nullable: false }) user: User; } diff --git a/src/subdomains/core/payment-link/entities/payment-quote.entity.ts b/src/subdomains/core/payment-link/entities/payment-quote.entity.ts index 786a7b1933..8751dc4aaf 100644 --- a/src/subdomains/core/payment-link/entities/payment-quote.entity.ts +++ b/src/subdomains/core/payment-link/entities/payment-quote.entity.ts @@ -2,7 +2,7 @@ import { Blockchain } from 'src/integration/blockchain/shared/enums/blockchain.e import { IEntity } from 'src/shared/models/entity'; import { Util } from 'src/shared/utils/util'; import { CryptoInput } from 'src/subdomains/supporting/payin/entities/crypto-input.entity'; -import { Column, Entity, ManyToOne, OneToMany } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, OneToMany } from 'typeorm'; import { TransferAmount, TransferAmountAsset, TransferMethod } from '../dto/payment-link.dto'; import { PaymentQuoteStatus, PaymentStandard } from '../enums'; import { PaymentActivation } from './payment-activation.entity'; @@ -16,6 +16,7 @@ export class PaymentQuote extends IEntity { @Column({ length: 256 }) status: PaymentQuoteStatus; + @Index() @ManyToOne(() => PaymentLinkPayment, (p) => p.quotes, { nullable: false }) payment: PaymentLinkPayment; diff --git a/src/subdomains/core/referral/reward/ref-reward.entity.ts b/src/subdomains/core/referral/reward/ref-reward.entity.ts index b82dccd82d..dab2c092e0 100644 --- a/src/subdomains/core/referral/reward/ref-reward.entity.ts +++ b/src/subdomains/core/referral/reward/ref-reward.entity.ts @@ -4,7 +4,7 @@ import { LiquidityManagementPipeline } from 'src/subdomains/core/liquidity-manag import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { Transaction } from 'src/subdomains/supporting/payment/entities/transaction.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { Reward } from '../../../../shared/models/reward.entity'; export enum RewardStatus { @@ -21,6 +21,7 @@ export enum RewardStatus { @Entity() export class RefReward extends Reward { + @Index() @ManyToOne(() => User, { nullable: false }) user: User; @@ -41,6 +42,7 @@ export class RefReward extends Reward { @JoinColumn() sourceTransaction?: Transaction; + @Index() @ManyToOne(() => LiquidityManagementPipeline, { nullable: true }) liquidityPipeline?: LiquidityManagementPipeline; diff --git a/src/subdomains/core/sell-crypto/process/buy-fiat.entity.ts b/src/subdomains/core/sell-crypto/process/buy-fiat.entity.ts index 12194e1dc7..ecbbcc3005 100644 --- a/src/subdomains/core/sell-crypto/process/buy-fiat.entity.ts +++ b/src/subdomains/core/sell-crypto/process/buy-fiat.entity.ts @@ -24,7 +24,7 @@ import { FeeType } from 'src/subdomains/supporting/payment/entities/fee.entity'; import { SpecialExternalAccount } from 'src/subdomains/supporting/payment/entities/special-external-account.entity'; import { Price, PriceStep } from 'src/subdomains/supporting/pricing/domain/entities/price'; import { PriceCurrency } from 'src/subdomains/supporting/pricing/services/pricing.service'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { FiatOutput } from '../../../supporting/fiat-output/fiat-output.entity'; import { Transaction } from '../../../supporting/payment/entities/transaction.entity'; import { AmlReason } from '../../aml/enums/aml-reason.enum'; @@ -40,15 +40,19 @@ export class BuyFiat extends IEntity { @JoinColumn() cryptoInput: CryptoInput; + @Index() @ManyToOne(() => FiatOutput, (o) => o.buyFiats, { nullable: true }) fiatOutput?: FiatOutput; + @Index() @ManyToOne(() => Sell, (sell) => sell.buyFiats, { nullable: false }) sell: Sell; + @Index() @ManyToOne(() => BankTx, { nullable: true }) bankTx?: BankTx; + @Index() @ManyToOne(() => BankData, { nullable: true }) bankData?: BankData; @@ -194,6 +198,7 @@ export class BuyFiat extends IEntity { @Column({ type: 'float', nullable: true }) outputReferenceAmount?: number; + @Index() @ManyToOne(() => Fiat, { eager: true, nullable: true }) outputReferenceAsset?: Fiat; diff --git a/src/subdomains/core/sell-crypto/route/sell.entity.ts b/src/subdomains/core/sell-crypto/route/sell.entity.ts index df770fdc2b..1a70d03a9b 100644 --- a/src/subdomains/core/sell-crypto/route/sell.entity.ts +++ b/src/subdomains/core/sell-crypto/route/sell.entity.ts @@ -5,7 +5,7 @@ import { BankData } from 'src/subdomains/generic/user/models/bank-data/bank-data import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { DepositRoute, RouteType } from 'src/subdomains/supporting/address-pool/route/deposit-route.entity'; import { CryptoInput } from 'src/subdomains/supporting/payin/entities/crypto-input.entity'; -import { Check, ChildEntity, Column, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Check, ChildEntity, Column, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { BuyFiat } from '../process/buy-fiat.entity'; @Check(`"active" = false OR "bankDataId" IS NOT NULL OR "type" <> 'Sell'`) @@ -14,6 +14,7 @@ export class Sell extends DepositRoute { @Column({ length: 256 }) iban: string; + @Index() @ManyToOne(() => Fiat, { eager: true, nullable: true }) fiat?: Fiat; @@ -26,6 +27,7 @@ export class Sell extends DepositRoute { @ManyToOne(() => User, (user) => user.sells, { nullable: false }) declare user: User; + @Index() @ManyToOne(() => BankData, (bankData) => bankData.sells, { nullable: true }) bankData?: BankData; diff --git a/src/subdomains/core/staking/entities/crypto-staking.entity.ts b/src/subdomains/core/staking/entities/crypto-staking.entity.ts index b9edf0d230..aa9517ea6f 100644 --- a/src/subdomains/core/staking/entities/crypto-staking.entity.ts +++ b/src/subdomains/core/staking/entities/crypto-staking.entity.ts @@ -1,6 +1,6 @@ import { IEntity } from 'src/shared/models/entity'; import { CryptoInput } from 'src/subdomains/supporting/payin/entities/crypto-input.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { Deposit } from '../../../supporting/address-pool/deposit/deposit.entity'; import { DepositRoute } from '../../../supporting/address-pool/route/deposit-route.entity'; import { PayoutType } from './staking-reward.entity'; @@ -56,6 +56,7 @@ export class CryptoStaking extends IEntity { @Column({ length: 256, nullable: false }) payoutType: PayoutType; + @Index() @ManyToOne(() => Deposit, { eager: true, nullable: true }) paybackDeposit?: Deposit; @@ -63,6 +64,7 @@ export class CryptoStaking extends IEntity { @JoinColumn() cryptoInput: CryptoInput; + @Index() @ManyToOne(() => DepositRoute, { nullable: false }) stakingRoute: Staking; diff --git a/src/subdomains/core/staking/entities/staking-ref-reward.entity.ts b/src/subdomains/core/staking/entities/staking-ref-reward.entity.ts index 1b8d9d5fe7..971e9124a1 100644 --- a/src/subdomains/core/staking/entities/staking-ref-reward.entity.ts +++ b/src/subdomains/core/staking/entities/staking-ref-reward.entity.ts @@ -1,5 +1,5 @@ import { User } from 'src/subdomains/generic/user/models/user/user.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { Reward } from '../../../../shared/models/reward.entity'; import { Staking } from './staking.entity'; @@ -10,9 +10,11 @@ export enum StakingRefType { @Entity() export class StakingRefReward extends Reward { + @Index() @ManyToOne(() => User, { nullable: false }) user: User; + @Index() @ManyToOne(() => Staking, (staking) => staking.rewards, { nullable: true }) staking?: Staking; diff --git a/src/subdomains/core/staking/entities/staking-reward.entity.ts b/src/subdomains/core/staking/entities/staking-reward.entity.ts index 1c10dc15da..f97832b012 100644 --- a/src/subdomains/core/staking/entities/staking-reward.entity.ts +++ b/src/subdomains/core/staking/entities/staking-reward.entity.ts @@ -20,6 +20,7 @@ export class StakingReward extends Reward { @Column({ length: 256 }) payoutType: PayoutType; + @Index() @ManyToOne(() => Staking, (staking) => staking.rewards, { nullable: false }) staking: Staking; diff --git a/src/subdomains/core/staking/entities/staking.entity.ts b/src/subdomains/core/staking/entities/staking.entity.ts index c83dfab106..e23b43b068 100644 --- a/src/subdomains/core/staking/entities/staking.entity.ts +++ b/src/subdomains/core/staking/entities/staking.entity.ts @@ -3,19 +3,23 @@ import { StakingReward } from 'src/subdomains/core/staking/entities/staking-rewa import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { Deposit } from 'src/subdomains/supporting/address-pool/deposit/deposit.entity'; import { DepositRoute } from 'src/subdomains/supporting/address-pool/route/deposit-route.entity'; -import { ChildEntity, Column, ManyToOne, OneToMany } from 'typeorm'; +import { ChildEntity, Column, Index, ManyToOne, OneToMany } from 'typeorm'; @ChildEntity() export class Staking extends DepositRoute { + @Index() @ManyToOne(() => Deposit, { eager: true, nullable: true }) rewardDeposit?: Deposit; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) rewardAsset?: Asset; + @Index() @ManyToOne(() => Deposit, { eager: true, nullable: true }) paybackDeposit?: Deposit; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) paybackAsset?: Asset; diff --git a/src/subdomains/core/trading/entities/trading-order.entity.ts b/src/subdomains/core/trading/entities/trading-order.entity.ts index ce8a5abc84..c62788aa8e 100644 --- a/src/subdomains/core/trading/entities/trading-order.entity.ts +++ b/src/subdomains/core/trading/entities/trading-order.entity.ts @@ -1,6 +1,6 @@ import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity } from 'src/shared/models/entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { TradingInfo } from '../dto/trading.dto'; import { TradingOrderStatus } from '../enums'; import { TradingRule } from './trading-rule.entity'; @@ -10,6 +10,7 @@ export class TradingOrder extends IEntity { @Column() status: TradingOrderStatus; + @Index() @ManyToOne(() => TradingRule, { nullable: false, eager: true }) tradingRule: TradingRule; @@ -25,9 +26,11 @@ export class TradingOrder extends IEntity { @Column({ type: 'float' }) priceImpact: number; + @Index() @ManyToOne(() => Asset, { nullable: false, eager: true }) assetIn: Asset; + @Index() @ManyToOne(() => Asset, { nullable: false, eager: true }) assetOut: Asset; diff --git a/src/subdomains/core/trading/entities/trading-rule.entity.ts b/src/subdomains/core/trading/entities/trading-rule.entity.ts index 0f6a25358d..d0ae78b8c7 100644 --- a/src/subdomains/core/trading/entities/trading-rule.entity.ts +++ b/src/subdomains/core/trading/entities/trading-rule.entity.ts @@ -3,7 +3,7 @@ import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity } from 'src/shared/models/entity'; import { Util } from 'src/shared/utils/util'; import { PriceSource } from 'src/subdomains/supporting/pricing/domain/entities/price-rule.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { TradingRuleStatus } from '../enums'; export interface PriceConfig { @@ -18,9 +18,11 @@ export class TradingRule extends IEntity { @Column() status: TradingRuleStatus; + @Index() @ManyToOne(() => Asset, { nullable: false, eager: true }) leftAsset: Asset; + @Index() @ManyToOne(() => Asset, { nullable: false, eager: true }) rightAsset: Asset; diff --git a/src/subdomains/generic/kyc/entities/kyc-file.entity.ts b/src/subdomains/generic/kyc/entities/kyc-file.entity.ts index 373c0b2090..15bd84cb76 100644 --- a/src/subdomains/generic/kyc/entities/kyc-file.entity.ts +++ b/src/subdomains/generic/kyc/entities/kyc-file.entity.ts @@ -1,7 +1,7 @@ import { Config } from 'src/config/config'; import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; -import { Column, Entity, ManyToOne, OneToMany } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, OneToMany } from 'typeorm'; import { FileSubType, FileType } from '../dto/kyc-file.dto'; import { KycLog } from './kyc-log.entity'; import { KycStep } from './kyc-step.entity'; @@ -26,9 +26,11 @@ export class KycFile extends IEntity { @Column({ length: 256, unique: true }) uid: string; + @Index() @ManyToOne(() => UserData, { nullable: false, eager: true }) userData: UserData; + @Index() @ManyToOne(() => KycStep, (s) => s.files, { nullable: true }) kycStep?: KycStep; diff --git a/src/subdomains/generic/kyc/entities/kyc-log.entity.ts b/src/subdomains/generic/kyc/entities/kyc-log.entity.ts index d773fce9b8..02ee58d9b4 100644 --- a/src/subdomains/generic/kyc/entities/kyc-log.entity.ts +++ b/src/subdomains/generic/kyc/entities/kyc-log.entity.ts @@ -1,6 +1,6 @@ import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; -import { Column, Entity, ManyToOne, TableInheritance } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, TableInheritance } from 'typeorm'; import { KycLogType } from '../enums/kyc.enum'; import { KycFile } from './kyc-file.entity'; @@ -16,6 +16,7 @@ export class KycLog extends IEntity { @Column({ length: 256, nullable: true }) pdfUrl?: string; + @Index() @ManyToOne(() => KycFile, (f) => f.logs, { nullable: true }) file?: KycFile; @@ -25,6 +26,7 @@ export class KycLog extends IEntity { @Column({ type: 'timestamp', nullable: true }) eventDate?: Date; + @Index() @ManyToOne(() => UserData, { nullable: false }) userData: UserData; diff --git a/src/subdomains/generic/kyc/entities/kyc-step.entity.ts b/src/subdomains/generic/kyc/entities/kyc-step.entity.ts index f3a6852c4f..f1012c66e8 100644 --- a/src/subdomains/generic/kyc/entities/kyc-step.entity.ts +++ b/src/subdomains/generic/kyc/entities/kyc-step.entity.ts @@ -21,6 +21,7 @@ export type KycStepResult = string | object; @Entity() @Index((s: KycStep) => [s.userData, s.name, s.type, s.sequenceNumber], { unique: true }) export class KycStep extends IEntity { + @Index() @ManyToOne(() => UserData, (userData) => userData.kycSteps, { nullable: false }) userData: UserData; diff --git a/src/subdomains/generic/kyc/entities/name-check-log.entity.ts b/src/subdomains/generic/kyc/entities/name-check-log.entity.ts index 4721c81dda..561d516e8e 100644 --- a/src/subdomains/generic/kyc/entities/name-check-log.entity.ts +++ b/src/subdomains/generic/kyc/entities/name-check-log.entity.ts @@ -1,4 +1,4 @@ -import { ChildEntity, Column, ManyToOne } from 'typeorm'; +import { ChildEntity, Column, Index, ManyToOne } from 'typeorm'; import { BankData } from '../../user/models/bank-data/bank-data.entity'; import { KycLog } from './kyc-log.entity'; @@ -26,6 +26,7 @@ export class NameCheckLog extends KycLog { @Column({ type: 'timestamp', nullable: true }) riskEvaluationDate?: Date; + @Index() @ManyToOne(() => BankData, { nullable: true }) bankData?: BankData; } diff --git a/src/subdomains/generic/kyc/entities/step-log.entity.ts b/src/subdomains/generic/kyc/entities/step-log.entity.ts index 86b4252c69..9679c646f1 100644 --- a/src/subdomains/generic/kyc/entities/step-log.entity.ts +++ b/src/subdomains/generic/kyc/entities/step-log.entity.ts @@ -1,10 +1,11 @@ -import { ChildEntity, Column, ManyToOne } from 'typeorm'; +import { ChildEntity, Column, Index, ManyToOne } from 'typeorm'; import { ReviewStatus } from '../enums/review-status.enum'; import { KycLog } from './kyc-log.entity'; import { KycStep } from './kyc-step.entity'; @ChildEntity() export class StepLog extends KycLog { + @Index() @ManyToOne(() => KycStep, (s) => s.logs, { onDelete: 'CASCADE' }) kycStep: KycStep; diff --git a/src/subdomains/generic/user/models/account-merge/account-merge.entity.ts b/src/subdomains/generic/user/models/account-merge/account-merge.entity.ts index cb798f7fba..7c2bea2040 100644 --- a/src/subdomains/generic/user/models/account-merge/account-merge.entity.ts +++ b/src/subdomains/generic/user/models/account-merge/account-merge.entity.ts @@ -12,9 +12,11 @@ export enum MergeReason { @Entity() export class AccountMerge extends IEntity { + @Index() @ManyToOne(() => UserData, { nullable: false }) master: UserData; + @Index() @ManyToOne(() => UserData, { nullable: false }) slave: UserData; diff --git a/src/subdomains/generic/user/models/bank-data/bank-data.entity.ts b/src/subdomains/generic/user/models/bank-data/bank-data.entity.ts index 0cf4bc8352..9b76377300 100644 --- a/src/subdomains/generic/user/models/bank-data/bank-data.entity.ts +++ b/src/subdomains/generic/user/models/bank-data/bank-data.entity.ts @@ -60,9 +60,11 @@ export class BankData extends IEntity { @Column({ default: false }) default: boolean; + @Index() @ManyToOne(() => Fiat, { nullable: true, eager: true }) preferredCurrency?: Fiat; + @Index() @ManyToOne(() => UserData, { nullable: false }) userData: UserData; diff --git a/src/subdomains/generic/user/models/organization/organization.entity.ts b/src/subdomains/generic/user/models/organization/organization.entity.ts index cfb83292a5..9eef99d2c7 100644 --- a/src/subdomains/generic/user/models/organization/organization.entity.ts +++ b/src/subdomains/generic/user/models/organization/organization.entity.ts @@ -1,6 +1,6 @@ import { Country } from 'src/shared/models/country/country.entity'; import { IEntity } from 'src/shared/models/entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm'; import { UserData } from '../user-data/user-data.entity'; import { LegalEntity, SignatoryPower } from '../user-data/user-data.enum'; @@ -40,6 +40,7 @@ export class Organization extends IEntity { // --- RELATIONS --- // + @Index() @ManyToOne(() => UserData, { nullable: true }) @JoinColumn() accountOpener?: UserData; @@ -50,6 +51,7 @@ export class Organization extends IEntity { @Column({ length: 256, nullable: true }) signatoryPower?: SignatoryPower; + @Index() @ManyToOne(() => Country, { eager: true, nullable: true }) country?: Country; diff --git a/src/subdomains/generic/user/models/recommendation/recommendation.entity.ts b/src/subdomains/generic/user/models/recommendation/recommendation.entity.ts index 5fa71b454a..baaae86f29 100644 --- a/src/subdomains/generic/user/models/recommendation/recommendation.entity.ts +++ b/src/subdomains/generic/user/models/recommendation/recommendation.entity.ts @@ -1,7 +1,7 @@ import { Config } from 'src/config/config'; import { IEntity } from 'src/shared/models/entity'; import { KycStep } from 'src/subdomains/generic/kyc/entities/kyc-step.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { UserData } from '../user-data/user-data.entity'; export enum RecommendationType { @@ -41,9 +41,11 @@ export class Recommendation extends IEntity { @Column({ type: 'timestamp', nullable: true }) confirmationDate: Date; // only set for recommendations created by Recommended + @Index() @ManyToOne(() => UserData, { nullable: false }) recommender: UserData; + @Index() @ManyToOne(() => UserData, { nullable: true }) recommended?: UserData; diff --git a/src/subdomains/generic/user/models/user-data-relation/user-data-relation.entity.ts b/src/subdomains/generic/user/models/user-data-relation/user-data-relation.entity.ts index f9b884820c..6ba7b16507 100644 --- a/src/subdomains/generic/user/models/user-data-relation/user-data-relation.entity.ts +++ b/src/subdomains/generic/user/models/user-data-relation/user-data-relation.entity.ts @@ -1,5 +1,5 @@ import { IEntity } from 'src/shared/models/entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { UserData } from '../user-data/user-data.entity'; import { SignatoryState, UserDataRelationState } from './dto/user-data-relation.enum'; @@ -12,9 +12,11 @@ export class UserDataRelation extends IEntity { signatory: SignatoryState; // --- REFERENCES --- // + @Index() @ManyToOne(() => UserData, (userData) => userData.accountRelations, { nullable: false }) account: UserData; + @Index() @ManyToOne(() => UserData, (userData) => userData.relatedAccountRelations, { nullable: false }) relatedAccount: UserData; } diff --git a/src/subdomains/generic/user/models/user-data/user-data.entity.ts b/src/subdomains/generic/user/models/user-data/user-data.entity.ts index f6a97a22c0..5433575c32 100644 --- a/src/subdomains/generic/user/models/user-data/user-data.entity.ts +++ b/src/subdomains/generic/user/models/user-data/user-data.entity.ts @@ -86,6 +86,7 @@ export class UserData extends IEntity { @Column({ length: 256, nullable: true }) verifiedName?: string; + @Index() @ManyToOne(() => Country, { eager: true, nullable: true }) verifiedCountry?: Country; @@ -101,9 +102,11 @@ export class UserData extends IEntity { @Column({ length: 256, nullable: true }) zip?: string; + @Index() @ManyToOne(() => Country, { eager: true }) country?: Country; + @Index() @ManyToOne(() => Country, { eager: true, nullable: true }) nationality?: Country; @@ -135,6 +138,7 @@ export class UserData extends IEntity { organizationZip?: string; // TODO remove + @Index() @ManyToOne(() => Country, { eager: true }) organizationCountry?: Country; @@ -159,9 +163,11 @@ export class UserData extends IEntity { @Column({ length: 256, nullable: true }) phone?: string; + @Index() @ManyToOne(() => Language, { eager: true, nullable: false }) language: Language; + @Index() @ManyToOne(() => Fiat, { eager: true }) currency?: Fiat; @@ -365,6 +371,7 @@ export class UserData extends IEntity { isTrustedReferrer: boolean; // References + @Index() @ManyToOne(() => Wallet, { nullable: true }) wallet?: Wallet; @@ -372,10 +379,12 @@ export class UserData extends IEntity { transactions?: Transaction[]; // TODO remove + @Index() @ManyToOne(() => UserData, { nullable: true }) @JoinColumn() accountOpener?: UserData; + @Index() @ManyToOne(() => Organization, { nullable: true, eager: true }) organization?: Organization; diff --git a/src/subdomains/generic/user/models/user/user.entity.ts b/src/subdomains/generic/user/models/user/user.entity.ts index 74ffbd86a7..88300c1bb5 100644 --- a/src/subdomains/generic/user/models/user/user.entity.ts +++ b/src/subdomains/generic/user/models/user/user.entity.ts @@ -37,9 +37,11 @@ export class User extends IEntity { @Column({ length: 256, nullable: true }) label?: string; + @Index() @ManyToOne(() => Wallet) wallet: Wallet; + @Index() @ManyToOne(() => CustodyProvider) custodyProvider: CustodyProvider; @@ -113,9 +115,11 @@ export class User extends IEntity { @OneToMany(() => Staking, (staking) => staking.user) stakingRoutes: Staking[]; + @Index() @ManyToOne(() => UserData, { nullable: false }) userData: UserData; + @Index() @ManyToOne(() => User, { nullable: true }) primaryUser: User; @@ -151,6 +155,7 @@ export class User extends IEntity { @OneToMany(() => StakingRefReward, (reward) => reward.user) stakingRefRewards: StakingRefReward[]; + @Index() @ManyToOne(() => Asset, { nullable: true, eager: true }) refAsset: Asset; @@ -167,6 +172,7 @@ export class User extends IEntity { @Column({ nullable: true }) custodyAddressType: CustodyAddressType; + @Index() @ManyToOne(() => CustodyAccount, { nullable: true }) custodyAccount?: CustodyAccount; diff --git a/src/subdomains/generic/user/models/wallet/wallet.entity.ts b/src/subdomains/generic/user/models/wallet/wallet.entity.ts index 049a3e528b..e939dfbcce 100644 --- a/src/subdomains/generic/user/models/wallet/wallet.entity.ts +++ b/src/subdomains/generic/user/models/wallet/wallet.entity.ts @@ -21,6 +21,7 @@ export enum WebhookConfigOption { @Entity() export class Wallet extends IEntity { + @Index() @ManyToOne(() => User, { nullable: true }) owner?: User; diff --git a/src/subdomains/generic/user/services/webhook/webhook.entity.ts b/src/subdomains/generic/user/services/webhook/webhook.entity.ts index 8aa559927b..79649ba2dc 100644 --- a/src/subdomains/generic/user/services/webhook/webhook.entity.ts +++ b/src/subdomains/generic/user/services/webhook/webhook.entity.ts @@ -1,5 +1,5 @@ import { IEntity, UpdateResult } from 'src/shared/models/entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { UserData } from '../../models/user-data/user-data.entity'; import { User } from '../../models/user/user.entity'; import { Wallet } from '../../models/wallet/wallet.entity'; @@ -29,12 +29,15 @@ export class Webhook extends IEntity { isComplete: boolean; // References + @Index() @ManyToOne(() => User, { nullable: true, eager: true }) user?: User; + @Index() @ManyToOne(() => UserData, { nullable: false, eager: true }) userData: UserData; + @Index() @ManyToOne(() => Wallet, { nullable: false, eager: true }) wallet: Wallet; diff --git a/src/subdomains/supporting/bank-tx/bank-tx-repeat/bank-tx-repeat.entity.ts b/src/subdomains/supporting/bank-tx/bank-tx-repeat/bank-tx-repeat.entity.ts index c541cde308..e279777865 100644 --- a/src/subdomains/supporting/bank-tx/bank-tx-repeat/bank-tx-repeat.entity.ts +++ b/src/subdomains/supporting/bank-tx/bank-tx-repeat/bank-tx-repeat.entity.ts @@ -2,7 +2,7 @@ import { Blockchain } from 'src/integration/blockchain/shared/enums/blockchain.e import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity } from 'src/shared/models/entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { BankService } from '../../bank/bank/bank.service'; import { FiatOutput } from '../../fiat-output/fiat-output.entity'; import { Transaction } from '../../payment/entities/transaction.entity'; @@ -30,6 +30,7 @@ export class BankTxRepeat extends IEntity { @JoinColumn() transaction?: Transaction; + @Index() @ManyToOne(() => User, { nullable: true }) user?: User; diff --git a/src/subdomains/supporting/bank-tx/bank-tx-return/bank-tx-return.entity.ts b/src/subdomains/supporting/bank-tx/bank-tx-return/bank-tx-return.entity.ts index 6abdb4da9a..98a11e7bf6 100644 --- a/src/subdomains/supporting/bank-tx/bank-tx-return/bank-tx-return.entity.ts +++ b/src/subdomains/supporting/bank-tx/bank-tx-return/bank-tx-return.entity.ts @@ -4,7 +4,7 @@ import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { CreditorData } from 'src/subdomains/core/buy-crypto/process/entities/buy-crypto.entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { Wallet } from 'src/subdomains/generic/user/models/wallet/wallet.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { BankService } from '../../bank/bank/bank.service'; import { FiatOutput } from '../../fiat-output/fiat-output.entity'; import { PaymentMethod } from '../../payment/dto/payment-method.enum'; @@ -85,6 +85,7 @@ export class BankTxReturn extends IEntity { @Column({ type: 'timestamp', nullable: true }) mailSendDate?: Date; + @Index() @ManyToOne(() => UserData, (userData) => userData.bankTxReturns, { nullable: true, eager: true }) userData?: UserData; diff --git a/src/subdomains/supporting/bank-tx/bank-tx/entities/bank-tx.entity.ts b/src/subdomains/supporting/bank-tx/bank-tx/entities/bank-tx.entity.ts index 09811187be..47cd168325 100644 --- a/src/subdomains/supporting/bank-tx/bank-tx/entities/bank-tx.entity.ts +++ b/src/subdomains/supporting/bank-tx/bank-tx/entities/bank-tx.entity.ts @@ -11,7 +11,7 @@ import { FiatOutput } from 'src/subdomains/supporting/fiat-output/fiat-output.en import { BankExchangeType } from 'src/subdomains/supporting/log/dto/log.dto'; import { FiatPaymentMethod, PaymentMethod } from 'src/subdomains/supporting/payment/dto/payment-method.enum'; import { Price } from 'src/subdomains/supporting/pricing/domain/entities/price'; -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { SpecialExternalAccount, SpecialExternalAccountType, @@ -224,6 +224,7 @@ export class BankTx extends IEntity { @Column({ length: 256, nullable: true }) subFamilyCode?: string; + @Index() @ManyToOne(() => BankTxBatch, (batch) => batch.transactions, { nullable: true }) batch?: BankTxBatch; diff --git a/src/subdomains/supporting/bank/virtual-iban/virtual-iban.entity.ts b/src/subdomains/supporting/bank/virtual-iban/virtual-iban.entity.ts index 4b3c3d449f..b40ede1880 100644 --- a/src/subdomains/supporting/bank/virtual-iban/virtual-iban.entity.ts +++ b/src/subdomains/supporting/bank/virtual-iban/virtual-iban.entity.ts @@ -27,6 +27,7 @@ export class VirtualIban extends IEntity { @Column({ length: 256, nullable: true }) yapealAccountUid?: string; + @Index() @ManyToOne(() => Fiat, { nullable: false, eager: true }) currency: Fiat; @@ -36,9 +37,11 @@ export class VirtualIban extends IEntity { @Column({ length: 256, nullable: true }) status?: VirtualIbanStatus; + @Index() @ManyToOne(() => UserData, (userData) => userData.virtualIbans, { nullable: false }) userData: UserData; + @Index() @ManyToOne(() => Bank, { nullable: false, eager: true }) bank: Bank; @@ -54,6 +57,7 @@ export class VirtualIban extends IEntity { @Column({ length: 256, nullable: true }) label?: string; + @Index() @ManyToOne(() => Buy, { nullable: true, eager: true }) buy?: Buy; } diff --git a/src/subdomains/supporting/dex/entities/liquidity-order.entity.ts b/src/subdomains/supporting/dex/entities/liquidity-order.entity.ts index a6951fe5ce..0a93eb08a8 100644 --- a/src/subdomains/supporting/dex/entities/liquidity-order.entity.ts +++ b/src/subdomains/supporting/dex/entities/liquidity-order.entity.ts @@ -38,12 +38,14 @@ export class LiquidityOrder extends IEntity { @Column({ length: 256 }) chain: Blockchain; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) referenceAsset?: Asset; @Column({ type: 'float' }) referenceAmount: number; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) targetAsset?: Asset; @@ -59,6 +61,7 @@ export class LiquidityOrder extends IEntity { @Column({ default: false }) isComplete: boolean; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) swapAsset?: Asset; @@ -74,6 +77,7 @@ export class LiquidityOrder extends IEntity { @Column({ type: 'float', nullable: true }) purchasedAmount?: number; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) feeAsset?: Asset; diff --git a/src/subdomains/supporting/fiat-output/fiat-output.entity.ts b/src/subdomains/supporting/fiat-output/fiat-output.entity.ts index 2166f23171..ac6a6fdcf3 100644 --- a/src/subdomains/supporting/fiat-output/fiat-output.entity.ts +++ b/src/subdomains/supporting/fiat-output/fiat-output.entity.ts @@ -3,7 +3,7 @@ import { BuyCrypto } from 'src/subdomains/core/buy-crypto/process/entities/buy-c import { BuyFiat } from 'src/subdomains/core/sell-crypto/process/buy-fiat.entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { BankTxRepeat } from '../bank-tx/bank-tx-repeat/bank-tx-repeat.entity'; import { BankTxReturn } from '../bank-tx/bank-tx-return/bank-tx-return.entity'; import { BankTx } from '../bank-tx/bank-tx/entities/bank-tx.entity'; @@ -43,6 +43,7 @@ export class FiatOutput extends IEntity { @JoinColumn() bankTx?: BankTx; + @Index() @ManyToOne(() => Bank, { nullable: true, eager: true }) bank: Bank; diff --git a/src/subdomains/supporting/mros/mros.entity.ts b/src/subdomains/supporting/mros/mros.entity.ts index bf7c747e87..6695682946 100644 --- a/src/subdomains/supporting/mros/mros.entity.ts +++ b/src/subdomains/supporting/mros/mros.entity.ts @@ -1,7 +1,7 @@ import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { Transaction } from 'src/subdomains/supporting/payment/entities/transaction.entity'; -import { Column, Entity, JoinTable, ManyToMany, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, JoinTable, ManyToMany, ManyToOne } from 'typeorm'; import { MrosStatus } from './mros-status.enum'; export interface MrosPersonOverrides { @@ -18,6 +18,7 @@ export interface MrosPersonOverrides { @Entity() export class Mros extends IEntity { + @Index() @ManyToOne(() => UserData, { nullable: false }) userData: UserData; diff --git a/src/subdomains/supporting/notification/entities/notification.entity.ts b/src/subdomains/supporting/notification/entities/notification.entity.ts index 9bf0597a76..a3bf6976ce 100644 --- a/src/subdomains/supporting/notification/entities/notification.entity.ts +++ b/src/subdomains/supporting/notification/entities/notification.entity.ts @@ -1,6 +1,6 @@ import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { MailContext, MailType } from '../enums'; export interface NotificationOptions { @@ -37,6 +37,7 @@ export class Notification extends IEntity { @Column({ type: 'float', nullable: true }) debounce?: number; + @Index() @ManyToOne(() => UserData, { nullable: true }) userData?: UserData; diff --git a/src/subdomains/supporting/payin/entities/crypto-input.entity.ts b/src/subdomains/supporting/payin/entities/crypto-input.entity.ts index d924a7acd9..b7a6bead64 100644 --- a/src/subdomains/supporting/payin/entities/crypto-input.entity.ts +++ b/src/subdomains/supporting/payin/entities/crypto-input.entity.ts @@ -109,6 +109,7 @@ export class CryptoInput extends IEntity { @Column({ type: 'float', nullable: true }) forwardFeeAmountChf?: number; + @Index() @ManyToOne(() => Asset, { nullable: true, eager: true }) asset?: Asset; @@ -118,6 +119,7 @@ export class CryptoInput extends IEntity { @Column({ length: 256, nullable: true }) purpose?: PayInPurpose; + @Index() @ManyToOne(() => DepositRoute, { eager: true, nullable: true }) route?: DepositRoute; @@ -131,9 +133,11 @@ export class CryptoInput extends IEntity { @OneToOne(() => BuyCrypto, (buyCrypto) => buyCrypto.cryptoInput, { nullable: true }) buyCrypto?: BuyCrypto; + @Index() @ManyToOne(() => PaymentLinkPayment, (payment) => payment.cryptoInputs, { nullable: true }) paymentLinkPayment?: PaymentLinkPayment; + @Index() @ManyToOne(() => PaymentQuote, (quote) => quote.cryptoInputs, { nullable: true }) paymentQuote?: PaymentQuote; diff --git a/src/subdomains/supporting/payment/entities/fee.entity.ts b/src/subdomains/supporting/payment/entities/fee.entity.ts index 24266963c9..1391b978f5 100644 --- a/src/subdomains/supporting/payment/entities/fee.entity.ts +++ b/src/subdomains/supporting/payment/entities/fee.entity.ts @@ -5,7 +5,7 @@ import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { Fiat } from 'src/shared/models/fiat/fiat.entity'; import { AccountType } from 'src/subdomains/generic/user/models/user-data/account-type.enum'; import { Wallet } from 'src/subdomains/generic/user/models/wallet/wallet.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { Bank } from '../../bank/bank/bank.entity'; import { FeeRequest } from '../services/fee.service'; @@ -80,9 +80,11 @@ export class Fee extends IEntity { @Column({ type: 'text', nullable: true }) financialTypes?: string; // semicolon separated financialTypes + @Index() @ManyToOne(() => Wallet, { nullable: true, eager: true }) wallet?: Wallet; + @Index() @ManyToOne(() => Bank, { nullable: true, eager: true }) bank?: Bank; diff --git a/src/subdomains/supporting/payment/entities/transaction-request.entity.ts b/src/subdomains/supporting/payment/entities/transaction-request.entity.ts index c1e031ce4c..f132296734 100644 --- a/src/subdomains/supporting/payment/entities/transaction-request.entity.ts +++ b/src/subdomains/supporting/payment/entities/transaction-request.entity.ts @@ -4,7 +4,7 @@ import { CustodyOrder } from 'src/subdomains/core/custody/entities/custody-order import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; import { PriceStep } from 'src/subdomains/supporting/pricing/domain/entities/price'; -import { Column, Entity, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { SupportIssue } from '../../support-issue/entities/support-issue.entity'; import { FeeDto } from '../dto/fee.dto'; import { PaymentMethod } from '../dto/payment-method.enum'; @@ -106,6 +106,7 @@ export class TransactionRequest extends IEntity { @Column({ default: false }) isComplete: boolean; + @Index() @ManyToOne(() => User, { nullable: false }) user: User; diff --git a/src/subdomains/supporting/payment/entities/transaction-risk-assessment.entity.ts b/src/subdomains/supporting/payment/entities/transaction-risk-assessment.entity.ts index c8a79fb4fe..c257a02bfb 100644 --- a/src/subdomains/supporting/payment/entities/transaction-risk-assessment.entity.ts +++ b/src/subdomains/supporting/payment/entities/transaction-risk-assessment.entity.ts @@ -1,5 +1,5 @@ import { IEntity } from 'src/shared/models/entity'; -import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm'; import { Transaction } from './transaction.entity'; export enum RiskType { @@ -41,6 +41,7 @@ export class TransactionRiskAssessment extends IEntity { @Column({ default: AssessmentStatus.CREATED }) status: AssessmentStatus; + @Index() @ManyToOne(() => Transaction, (t) => t.riskAssessments, { nullable: false }) @JoinColumn() transaction: Transaction; diff --git a/src/subdomains/supporting/payment/entities/transaction.entity.ts b/src/subdomains/supporting/payment/entities/transaction.entity.ts index 93c4153f60..384302e4a2 100644 --- a/src/subdomains/supporting/payment/entities/transaction.entity.ts +++ b/src/subdomains/supporting/payment/entities/transaction.entity.ts @@ -5,7 +5,7 @@ import { CustodyOrder } from 'src/subdomains/core/custody/entities/custody-order import { RefReward } from 'src/subdomains/core/referral/reward/ref-reward.entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { User } from 'src/subdomains/generic/user/models/user/user.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { BuyCrypto } from '../../../core/buy-crypto/process/entities/buy-crypto.entity'; import { BuyFiat } from '../../../core/sell-crypto/process/buy-fiat.entity'; import { BankTxRepeat } from '../../bank-tx/bank-tx-repeat/bank-tx-repeat.entity'; @@ -128,9 +128,11 @@ export class Transaction extends IEntity { @OneToMany(() => SupportIssue, (supportIssue) => supportIssue.transaction) supportIssues?: SupportIssue[]; + @Index() @ManyToOne(() => User, (user) => user.transactions, { nullable: true, eager: true }) user?: User; + @Index() @ManyToOne(() => UserData, (userData) => userData.transactions, { nullable: true }) userData?: UserData; diff --git a/src/subdomains/supporting/pricing/domain/entities/asset-price.entity.ts b/src/subdomains/supporting/pricing/domain/entities/asset-price.entity.ts index 875d4712b4..d0ddd927e0 100644 --- a/src/subdomains/supporting/pricing/domain/entities/asset-price.entity.ts +++ b/src/subdomains/supporting/pricing/domain/entities/asset-price.entity.ts @@ -1,9 +1,10 @@ import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity } from 'src/shared/models/entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; @Entity() export class AssetPrice extends IEntity { + @Index() @ManyToOne(() => Asset, (a) => a.prices) asset: Asset; diff --git a/src/subdomains/supporting/pricing/domain/entities/price-rule.entity.ts b/src/subdomains/supporting/pricing/domain/entities/price-rule.entity.ts index 2fc0e1dd2c..a44b54ffa2 100644 --- a/src/subdomains/supporting/pricing/domain/entities/price-rule.entity.ts +++ b/src/subdomains/supporting/pricing/domain/entities/price-rule.entity.ts @@ -2,7 +2,7 @@ import { Asset } from 'src/shared/models/asset/asset.entity'; import { IEntity } from 'src/shared/models/entity'; import { Fiat } from 'src/shared/models/fiat/fiat.entity'; import { Util } from 'src/shared/utils/util'; -import { Column, Entity, ManyToOne, OneToMany } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, OneToMany } from 'typeorm'; import { PricingProviderMap } from '../interfaces'; import { Price } from './price'; @@ -43,6 +43,7 @@ export class PriceRule extends IEntity { @OneToMany(() => Fiat, (f) => f.priceRule) fiats: Fiat[]; + @Index() @ManyToOne(() => Asset, { eager: true, nullable: true }) reference?: Asset; diff --git a/src/subdomains/supporting/recall/recall.entity.ts b/src/subdomains/supporting/recall/recall.entity.ts index 4ff4807d41..f0af285259 100644 --- a/src/subdomains/supporting/recall/recall.entity.ts +++ b/src/subdomains/supporting/recall/recall.entity.ts @@ -8,15 +8,18 @@ import { RecallReason } from './recall-reason.enum'; @Entity() @Index((r: Recall) => [r.bankTx, r.checkoutTx, r.sequence], { unique: true }) export class Recall extends IEntity { + @Index() @ManyToOne(() => BankTx) bankTx: BankTx; + @Index() @ManyToOne(() => CheckoutTx) checkoutTx: CheckoutTx; @Column({ type: 'int' }) sequence: number; + @Index() @ManyToOne(() => User, { nullable: true }) user?: User; diff --git a/src/subdomains/supporting/support-issue/entities/limit-request-log.entity.ts b/src/subdomains/supporting/support-issue/entities/limit-request-log.entity.ts index 07751acd1f..e3661a6c4b 100644 --- a/src/subdomains/supporting/support-issue/entities/limit-request-log.entity.ts +++ b/src/subdomains/supporting/support-issue/entities/limit-request-log.entity.ts @@ -1,9 +1,10 @@ -import { ChildEntity, Column, ManyToOne } from 'typeorm'; +import { ChildEntity, Column, Index, ManyToOne } from 'typeorm'; import { LimitRequest, LimitRequestDecision } from './limit-request.entity'; import { SupportLog } from './support-log.entity'; @ChildEntity() export class LimitRequestLog extends SupportLog { + @Index() @ManyToOne(() => LimitRequest, (s) => s.logs, { onDelete: 'CASCADE' }) limitRequest: LimitRequest; diff --git a/src/subdomains/supporting/support-issue/entities/support-issue-log.entity.ts b/src/subdomains/supporting/support-issue/entities/support-issue-log.entity.ts index 6260403d59..3c8d2a92ac 100644 --- a/src/subdomains/supporting/support-issue/entities/support-issue-log.entity.ts +++ b/src/subdomains/supporting/support-issue/entities/support-issue-log.entity.ts @@ -1,4 +1,4 @@ -import { ChildEntity, Column, ManyToOne } from 'typeorm'; +import { ChildEntity, Column, Index, ManyToOne } from 'typeorm'; import { Department } from '../enums/department.enum'; import { SupportIssueInternalState } from '../enums/support-issue.enum'; import { SupportIssue } from './support-issue.entity'; @@ -6,6 +6,7 @@ import { SupportLog } from './support-log.entity'; @ChildEntity() export class SupportIssueLog extends SupportLog { + @Index() @ManyToOne(() => SupportIssue, (s) => s.logs, { onDelete: 'CASCADE' }) supportIssue: SupportIssue; diff --git a/src/subdomains/supporting/support-issue/entities/support-issue.entity.ts b/src/subdomains/supporting/support-issue/entities/support-issue.entity.ts index 6356eb5927..43d516dade 100644 --- a/src/subdomains/supporting/support-issue/entities/support-issue.entity.ts +++ b/src/subdomains/supporting/support-issue/entities/support-issue.entity.ts @@ -2,7 +2,7 @@ import { Config } from 'src/config/config'; import { IEntity, UpdateResult } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; import { LimitRequest } from 'src/subdomains/supporting/support-issue/entities/limit-request.entity'; -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; +import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne } from 'typeorm'; import { TransactionRequest } from '../../payment/entities/transaction-request.entity'; import { Transaction } from '../../payment/entities/transaction.entity'; import { Department } from '../enums/department.enum'; @@ -36,15 +36,18 @@ export class SupportIssue extends IEntity { @Column({ type: 'text', nullable: true }) information?: string; + @Index() @ManyToOne(() => Transaction, (transaction) => transaction.supportIssues, { nullable: true, eager: true }) transaction?: Transaction; + @Index() @ManyToOne(() => TransactionRequest, (request) => request.supportIssues, { nullable: true, eager: true }) transactionRequest?: TransactionRequest; @OneToMany(() => SupportMessage, (supportMessage) => supportMessage.issue) messages: SupportMessage[]; + @Index() @ManyToOne(() => UserData, { nullable: false, eager: true }) userData: UserData; diff --git a/src/subdomains/supporting/support-issue/entities/support-log.entity.ts b/src/subdomains/supporting/support-issue/entities/support-log.entity.ts index 94ae83cec6..67b9b5c32b 100644 --- a/src/subdomains/supporting/support-issue/entities/support-log.entity.ts +++ b/src/subdomains/supporting/support-issue/entities/support-log.entity.ts @@ -1,6 +1,6 @@ import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; -import { Column, Entity, ManyToOne, TableInheritance } from 'typeorm'; +import { Column, Entity, Index, ManyToOne, TableInheritance } from 'typeorm'; import { SupportLogType } from '../enums/support-log.enum'; @Entity() @@ -21,6 +21,7 @@ export class SupportLog extends IEntity { @Column({ type: 'timestamp', nullable: true }) eventDate?: Date; + @Index() @ManyToOne(() => UserData, { nullable: false }) userData: UserData; } diff --git a/src/subdomains/supporting/support-issue/entities/support-message.entity.ts b/src/subdomains/supporting/support-issue/entities/support-message.entity.ts index 7927a1d29f..013c9ee915 100644 --- a/src/subdomains/supporting/support-issue/entities/support-message.entity.ts +++ b/src/subdomains/supporting/support-issue/entities/support-message.entity.ts @@ -1,6 +1,6 @@ import { IEntity } from 'src/shared/models/entity'; import { UserData } from 'src/subdomains/generic/user/models/user-data/user-data.entity'; -import { Column, Entity, ManyToOne } from 'typeorm'; +import { Column, Entity, Index, ManyToOne } from 'typeorm'; import { SupportIssue } from './support-issue.entity'; export const CustomerAuthor = 'Customer'; @@ -17,6 +17,7 @@ export class SupportMessage extends IEntity { @Column({ length: 256, nullable: true }) fileUrl?: string; + @Index() @ManyToOne(() => SupportIssue, (issue) => issue.messages, { nullable: false, eager: true }) issue: SupportIssue; From bc50e88715a05c06a404a82ad9a8278825fd5d67 Mon Sep 17 00:00:00 2001 From: David May <85513542+davidleomay@users.noreply.github.com> Date: Tue, 26 May 2026 16:26:17 +0200 Subject: [PATCH 3/4] fix(support): use case-insensitive search for compliance user name lookup (#3765) --- src/shared/utils/util.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index 74a4991d3d..68f1b3ae26 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -6,7 +6,7 @@ import { XMLParser, XMLValidator } from 'fast-xml-parser'; import { readFile } from 'fs'; import { isEqual } from 'lodash'; import sanitizeHtml from 'sanitize-html'; -import { FindOperator, Like } from 'typeorm'; +import { FindOperator, ILike } from 'typeorm'; import { IEntity, UpdateResult } from '../models/entity'; export type KeyType = { @@ -501,7 +501,7 @@ export class Util { // --- DB --- // static contains(search: string): FindOperator { - return Like(`%${search}%`); + return ILike(`%${search}%`); } // --- MISC --- // From 0fdd52d89109d1f3bba7bb5afd7113d36621ad4a Mon Sep 17 00:00:00 2001 From: Blume1977 Date: Tue, 26 May 2026 18:04:21 +0200 Subject: [PATCH 4/4] refactor(user/realunit): drop UserCapabilitiesDto.supportAvailable (#3761) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(user/realunit): drop UserCapabilitiesDto.supportAvailable Pair with realunit-app PR (settings → kontakt support tile rendered unconditionally). The capability flag was introduced in #3733 to surface support visibility as backend state. Product decision has since reversed: support must always be reachable, including pre-signin onboarding flows where the user does not yet have a verified mail. Once visibility is a constant, the flag has no decision left to surface — drop it from the DTO contract rather than freeze it at `true` and accumulate dead surface area. Other capability flags (canEditName / canEditMail / canEditPhone / canEditAddress) are kept; they still gate genuine business decisions driven by KYC step status. * chore: retrigger CI --------- Co-authored-by: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> --- .../models/user/dto/__tests__/user-dto.mapper.spec.ts | 8 -------- .../generic/user/models/user/dto/user-dto.mapper.ts | 8 +++----- .../generic/user/models/user/dto/user-v2.dto.ts | 5 ----- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/subdomains/generic/user/models/user/dto/__tests__/user-dto.mapper.spec.ts b/src/subdomains/generic/user/models/user/dto/__tests__/user-dto.mapper.spec.ts index b755a440d7..4fa414a7cf 100644 --- a/src/subdomains/generic/user/models/user/dto/__tests__/user-dto.mapper.spec.ts +++ b/src/subdomains/generic/user/models/user/dto/__tests__/user-dto.mapper.spec.ts @@ -167,14 +167,6 @@ describe('UserDtoMapper', () => { expect(result.capabilities.canEditName).toBe(false); }); - it('supportAvailable mirrors whether the user has a mail set', () => { - const withMail = UserDtoMapper.mapUser(buildUserData()); - const withoutMail = UserDtoMapper.mapUser(buildUserData({ mail: undefined })); - - expect(withMail.capabilities.supportAvailable).toBe(true); - expect(withoutMail.capabilities.supportAvailable).toBe(false); - }); - it('all edit flags collapse to false on KYC-terminated accounts', () => { const result = UserDtoMapper.mapUser(buildUserData({ kycLevel: KycLevel.REJECTED })); diff --git a/src/subdomains/generic/user/models/user/dto/user-dto.mapper.ts b/src/subdomains/generic/user/models/user/dto/user-dto.mapper.ts index 1b49e06a10..f9a953f84c 100644 --- a/src/subdomains/generic/user/models/user/dto/user-dto.mapper.ts +++ b/src/subdomains/generic/user/models/user/dto/user-dto.mapper.ts @@ -75,20 +75,18 @@ export class UserDtoMapper { } // Per-action capabilities. Mirrors the gating the realunit-app cubits - // were re-implementing locally (settings-edit visibility, support-link - // visibility) — surfacing them here lets the app render UI affordances - // without iterating step status. + // were re-implementing locally (settings-edit visibility) — surfacing + // them here lets the app render UI affordances without iterating step + // status. private static computeCapabilities(userData: UserData): UserCapabilitiesDto { const personalDataLocked = userData .getStepsWith(KycStepName.PERSONAL_DATA) .some((s) => s.isCompleted || s.isInReview); - const hasVerifiedMail = !!userData.mail; return { canEditName: !personalDataLocked, canEditMail: !userData.isKycTerminated, canEditPhone: !userData.isKycTerminated, canEditAddress: !personalDataLocked, - supportAvailable: hasVerifiedMail, }; } diff --git a/src/subdomains/generic/user/models/user/dto/user-v2.dto.ts b/src/subdomains/generic/user/models/user/dto/user-v2.dto.ts index ce4c474fba..b9435f59f5 100644 --- a/src/subdomains/generic/user/models/user/dto/user-v2.dto.ts +++ b/src/subdomains/generic/user/models/user/dto/user-v2.dto.ts @@ -159,11 +159,6 @@ export class UserCapabilitiesDto { description: 'Whether the user may edit their postal address.', }) canEditAddress: boolean; - - @ApiProperty({ - description: 'Whether the support / ticket flow is currently available for this user (requires a verified email).', - }) - supportAvailable: boolean; } export class UserV2Dto {