From d85a779bbdf9e025ddddf4c764750e449834ede0 Mon Sep 17 00:00:00 2001 From: David May <85513542+davidleomay@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:58:11 +0100 Subject: [PATCH 1/3] feat: moved custom balance env to settings (#3495) --- .env.example | 3 --- src/config/config.ts | 5 ----- src/shared/models/setting/setting-schema.registry.ts | 4 ++++ src/shared/models/setting/setting.service.ts | 10 +++++++++- src/subdomains/supporting/log/log-job.service.ts | 7 ++++--- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index 925873eb71..2e20f6cafe 100644 --- a/.env.example +++ b/.env.example @@ -290,9 +290,6 @@ REALUNIT_BANK_IBAN= REALUNIT_BANK_BIC= REALUNIT_BANK_NAME= -CUSTOM_BALANCE_ASSETS= -CUSTOM_BALANCE_ADDRESSES= - REQUEST_KNOWN_IPS= CRON_JOB_DELAY= \ No newline at end of file diff --git a/src/config/config.ts b/src/config/config.ts index 2d1db4f2ee..bf73ac0ded 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -625,11 +625,6 @@ export class Configuration { apiKey: process.env.COIN_GECKO_API_KEY, }; - financialLog = { - customAssets: process.env.CUSTOM_BALANCE_ASSETS?.split(';') ?? [], // asset uniqueName - customAddresses: process.env.CUSTOM_BALANCE_ADDRESSES?.split(';') ?? [], - }; - payment = { timeoutDelay: +(process.env.PAYMENT_TIMEOUT_DELAY ?? 0), evmSeed: process.env.PAYMENT_EVM_SEED, diff --git a/src/shared/models/setting/setting-schema.registry.ts b/src/shared/models/setting/setting-schema.registry.ts index d02f5a2117..90abd1ff42 100644 --- a/src/shared/models/setting/setting-schema.registry.ts +++ b/src/shared/models/setting/setting-schema.registry.ts @@ -25,6 +25,10 @@ export const SettingSchemaRegistry: Record = { // IP Blacklist ipBlacklist: 'string[]', + + // Custom Balance Settings + customBalanceAddresses: 'string[]', + customBalanceAssets: 'string[]', // asset unique name }; export function isArraySchema(schema: SettingSchema): schema is ArraySchema { diff --git a/src/shared/models/setting/setting.service.ts b/src/shared/models/setting/setting.service.ts index f3cbef346f..d0a62256fd 100644 --- a/src/shared/models/setting/setting.service.ts +++ b/src/shared/models/setting/setting.service.ts @@ -4,9 +4,9 @@ import { validate } from 'class-validator'; import { Process } from 'src/shared/services/process.service'; import { CustomSignUpFeesDto } from './dto/custom-sign-up-fees.dto'; import { UpdateProcessDto } from './dto/update-process.dto'; +import { isArraySchema, isPrimitiveSchema, SettingSchema, SettingSchemaRegistry } from './setting-schema.registry'; import { Setting } from './setting.entity'; import { SettingRepository } from './setting.repository'; -import { isArraySchema, isPrimitiveSchema, SettingSchema, SettingSchemaRegistry } from './setting-schema.registry'; @Injectable() export class SettingService { @@ -104,6 +104,14 @@ export class SettingService { return this.getObjCached('ipBlacklist', []); } + async getCustomBalanceSettings(): Promise<{ addresses: string[]; assets: string[] }> { + const [addresses, assets] = await Promise.all([ + this.getObjCached('customBalanceAddresses', []), + this.getObjCached('customBalanceAssets', []), + ]); + return { addresses, assets }; + } + async addIpToBlacklist(ip: string): Promise { const ipBlacklist = await this.getIpBlacklist(); diff --git a/src/subdomains/supporting/log/log-job.service.ts b/src/subdomains/supporting/log/log-job.service.ts index fc8cd154f1..fb673c829d 100644 --- a/src/subdomains/supporting/log/log-job.service.ts +++ b/src/subdomains/supporting/log/log-job.service.ts @@ -206,8 +206,9 @@ export class LogJobService { } private async getAssetLog(assets: Asset[]): Promise { - // custom balance - const customAssets = assets.filter((a) => Config.financialLog.customAssets?.includes(a.uniqueName)); + // custom balance settings + const customBalanceSettings = await this.settingService.getCustomBalanceSettings(); + const customAssets = assets.filter((a) => customBalanceSettings.assets.includes(a.uniqueName)); const customAssetMap = Util.groupBy(customAssets, 'blockchain'); const liqAddresses = new Map( @@ -236,7 +237,7 @@ export class LogJobService { } const balances = await Util.timeout( - this.getCustomBalances(client, a, Config.financialLog.customAddresses).then((b) => b.flat()), + this.getCustomBalances(client, a, customBalanceSettings.addresses).then((b) => b.flat()), 30000, ); return { blockchain: b, balances }; From e33d1a0e22545869edc96cf6aeb612a1dc5b2edf Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Mon, 23 Mar 2026 10:59:37 +0100 Subject: [PATCH 2/3] feat: return remittanceInfo in RealUnit buy endpoint (#3498) * feat: return remittanceInfo in RealUnit buy payment info Add the bankUsage (purpose of payment) to the RealUnit buy endpoint response so the app can display it to the user for bank transfers. * fix: remove German from API description * fix: use buy.bankUsage directly instead of buyPaymentInfo.remittanceInfo * fix: use buy.bankUsage directly for QR code generation as well --- src/subdomains/supporting/realunit/dto/realunit.dto.ts | 3 +++ src/subdomains/supporting/realunit/realunit.service.ts | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/subdomains/supporting/realunit/dto/realunit.dto.ts b/src/subdomains/supporting/realunit/dto/realunit.dto.ts index b62099a2fe..5acf0f8f81 100644 --- a/src/subdomains/supporting/realunit/dto/realunit.dto.ts +++ b/src/subdomains/supporting/realunit/dto/realunit.dto.ts @@ -344,6 +344,9 @@ export class RealUnitPaymentInfoDto { @ApiPropertyOptional({ description: 'QR code for payment (Swiss QR-bill or GiroCode)' }) paymentRequest?: string; + @ApiPropertyOptional({ description: 'Purpose of payment for bank transfer' }) + remittanceInfo?: string; + @ApiProperty() isValid: boolean; diff --git a/src/subdomains/supporting/realunit/realunit.service.ts b/src/subdomains/supporting/realunit/realunit.service.ts index ce618a6432..364bee79e6 100644 --- a/src/subdomains/supporting/realunit/realunit.service.ts +++ b/src/subdomains/supporting/realunit/realunit.service.ts @@ -446,12 +446,13 @@ export class RealUnitService { ? this.generatePaymentRequest( currencyName, buyPaymentInfo.amount, - buyPaymentInfo.remittanceInfo, + buy.bankUsage, realunitBank, realunitAddress, user.userData, ) : undefined, + remittanceInfo: buy.active ? buy.bankUsage : undefined, isValid: buyPaymentInfo.isValid, error: buyPaymentInfo.error, }; From fbacfe6e428330aceb4af8419fbec14c89787e4c Mon Sep 17 00:00:00 2001 From: bernd2022 <104787072+bernd2022@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:39:42 +0100 Subject: [PATCH 3/3] Feat: enrich compliance user details with additional data (#3497) Add IP logs, support issues, bank txs, crypto inputs to user data support endpoint. Extend existing DTOs with more fields (chargebackDate, amlReason, bankData status, etc). --- src/shared/models/ip-log/ip-log.service.ts | 8 ++ .../process/services/buy-fiat.service.ts | 8 ++ .../support/dto/user-data-support.dto.ts | 75 ++++++++++ .../generic/support/support.module.ts | 2 + .../generic/support/support.service.ts | 136 ++++++++++++++++-- .../bank-tx/services/bank-tx.service.ts | 8 ++ .../payin/services/payin.service.ts | 8 ++ .../payment/services/transaction.service.ts | 1 + .../services/support-issue.service.ts | 8 ++ 9 files changed, 245 insertions(+), 9 deletions(-) diff --git a/src/shared/models/ip-log/ip-log.service.ts b/src/shared/models/ip-log/ip-log.service.ts index 96aed1d9eb..fb6e8ef1d3 100644 --- a/src/shared/models/ip-log/ip-log.service.ts +++ b/src/shared/models/ip-log/ip-log.service.ts @@ -53,6 +53,14 @@ export class IpLogService { return this.ipLogRepo.save(ipLog); } + async getByUserDataId(userDataId: number, limit = 50): Promise { + return this.ipLogRepo.find({ + where: { userData: { id: userDataId } }, + order: { created: 'DESC' }, + take: limit, + }); + } + async getLoginCountries(userDataId: number, dateFrom: Date, dateTo = new Date()): Promise { const nearestLog = await this.idCache.get(Util.isoDate(dateFrom), () => this.ipLogRepo.findOne({ where: { created: LessThanOrEqual(dateFrom) }, order: { id: 'DESC' } }), diff --git a/src/subdomains/core/sell-crypto/process/services/buy-fiat.service.ts b/src/subdomains/core/sell-crypto/process/services/buy-fiat.service.ts index 87b7db4256..c3b94a685d 100644 --- a/src/subdomains/core/sell-crypto/process/services/buy-fiat.service.ts +++ b/src/subdomains/core/sell-crypto/process/services/buy-fiat.service.ts @@ -283,6 +283,14 @@ export class BuyFiatService { return this.buyFiatRepo.findOne({ where: { transaction: { id: transactionId } }, relations }); } + async getBuyFiatsByTransactionIds(transactionIds: number[]): Promise { + if (!transactionIds.length) return []; + return this.buyFiatRepo.find({ + where: { transaction: { id: In(transactionIds) } }, + relations: { transaction: true, fiatOutput: { bankTx: true } }, + }); + } + async getBuyFiat(from: Date, relations?: FindOptionsRelations): Promise { return this.buyFiatRepo.find({ where: { transaction: { created: MoreThan(from) } }, relations }); } diff --git a/src/subdomains/generic/support/dto/user-data-support.dto.ts b/src/subdomains/generic/support/dto/user-data-support.dto.ts index f0e75eeb91..9f13c9e133 100644 --- a/src/subdomains/generic/support/dto/user-data-support.dto.ts +++ b/src/subdomains/generic/support/dto/user-data-support.dto.ts @@ -28,6 +28,7 @@ export class BankTxSupportInfo { type: BankTxType; name?: string; iban?: string; + remittanceInfo?: string; } export class UserSupportInfo { @@ -45,6 +46,8 @@ export class TransactionSupportInfo { sourceType: string; amountInChf?: number; amlCheck?: string; + chargebackDate?: Date; + amlReason?: string; created: Date; } @@ -87,16 +90,24 @@ export class BankDataSupportInfo { id: number; iban: string; name: string; + type?: string; + status?: string; approved: boolean; + manualApproved?: boolean; + active: boolean; + comment?: string; + created: Date; } export class BuySupportInfo { id: number; + iban?: string; bankUsage: string; assetName: string; blockchain: string; volume: number; active: boolean; + created: Date; } export class SellSupportInfo { @@ -104,6 +115,8 @@ export class SellSupportInfo { iban: string; fiatName?: string; volume: number; + active: boolean; + created: Date; } export class TransactionListEntry { @@ -177,12 +190,74 @@ export class RecommendationGraph { rootId: number; } +export class SupportMessageSupportInfo { + author: string; + message?: string; + created: Date; +} + +export class SupportIssueSupportInfo { + id: number; + uid: string; + type: string; + state: string; + reason: string; + name: string; + clerk?: string; + department?: string; + information?: string; + messages: SupportMessageSupportInfo[]; + transaction?: { + id: number; + uid: string; + type?: string; + sourceType: string; + amountInChf?: number; + amlCheck?: string; + }; + limitRequest?: { + limit: number; + acceptedLimit?: number; + decision?: string; + fundOrigin: string; + }; + created: Date; +} + +export class CryptoInputSupportInfo { + id: number; + transactionId?: number; + inTxId: string; + inTxExplorerUrl?: string; + status?: string; + amount: number; + assetName?: string; + blockchain?: string; + senderAddresses?: string; + returnTxId?: string; + returnTxExplorerUrl?: string; + purpose?: string; +} + +export class IpLogSupportInfo { + id: number; + ip: string; + country?: string; + url: string; + result: boolean; + created: Date; +} + export class UserDataSupportInfoDetails { userData: UserData; kycFiles: KycFile[]; kycSteps: KycStepSupportInfo[]; kycLogs: KycLogSupportInfo[]; transactions: TransactionSupportInfo[]; + bankTxs: BankTxSupportInfo[]; + cryptoInputs: CryptoInputSupportInfo[]; + ipLogs: IpLogSupportInfo[]; + supportIssues: SupportIssueSupportInfo[]; users: UserSupportInfo[]; bankDatas: BankDataSupportInfo[]; buyRoutes: BuySupportInfo[]; diff --git a/src/subdomains/generic/support/support.module.ts b/src/subdomains/generic/support/support.module.ts index aa4e4b0b46..43177694ca 100644 --- a/src/subdomains/generic/support/support.module.ts +++ b/src/subdomains/generic/support/support.module.ts @@ -7,6 +7,7 @@ import { BankTxModule } from 'src/subdomains/supporting/bank-tx/bank-tx.module'; import { PayInModule } from 'src/subdomains/supporting/payin/payin.module'; import { PaymentModule } from 'src/subdomains/supporting/payment/payment.module'; import { TransactionModule } from 'src/subdomains/supporting/payment/transaction.module'; +import { SupportIssueModule } from 'src/subdomains/supporting/support-issue/support-issue.module'; import { KycModule } from '../kyc/kyc.module'; import { UserModule } from '../user/user.module'; import { SupportController } from './support.controller'; @@ -23,6 +24,7 @@ import { SupportService } from './support.service'; BankTxModule, KycModule, TransactionModule, + SupportIssueModule, forwardRef(() => PaymentModule), ], controllers: [SupportController], diff --git a/src/subdomains/generic/support/support.service.ts b/src/subdomains/generic/support/support.service.ts index 6ad4779616..904fafdfb4 100644 --- a/src/subdomains/generic/support/support.service.ts +++ b/src/subdomains/generic/support/support.service.ts @@ -24,6 +24,12 @@ import { BankService } from 'src/subdomains/supporting/bank/bank/bank.service'; import { VirtualIbanService } from 'src/subdomains/supporting/bank/virtual-iban/virtual-iban.service'; import { PayInService } from 'src/subdomains/supporting/payin/services/payin.service'; import { Transaction } from 'src/subdomains/supporting/payment/entities/transaction.entity'; +import { IpLog } from 'src/shared/models/ip-log/ip-log.entity'; +import { IpLogService } from 'src/shared/models/ip-log/ip-log.service'; +import { txExplorerUrl } from 'src/integration/blockchain/shared/util/blockchain.util'; +import { CryptoInput } from 'src/subdomains/supporting/payin/entities/crypto-input.entity'; +import { SupportIssue } from 'src/subdomains/supporting/support-issue/entities/support-issue.entity'; +import { SupportIssueService } from 'src/subdomains/supporting/support-issue/services/support-issue.service'; import { TransactionHelper } from 'src/subdomains/supporting/payment/services/transaction-helper'; import { TransactionService } from 'src/subdomains/supporting/payment/services/transaction.service'; import { KycLog } from '../kyc/entities/kyc-log.entity'; @@ -45,6 +51,9 @@ import { BankDataSupportInfo, BankTxSupportInfo, BuySupportInfo, + CryptoInputSupportInfo, + IpLogSupportInfo, + SupportIssueSupportInfo, ComplianceSearchType, KycFileListEntry, KycFileYearlyStats, @@ -96,6 +105,8 @@ export class SupportService { private readonly transactionHelper: TransactionHelper, private readonly settingService: SettingService, private readonly recommendationService: RecommendationService, + private readonly ipLogService: IpLogService, + private readonly supportIssueService: SupportIssueService, ) {} async getUserDataDetails(id: number): Promise { @@ -103,17 +114,38 @@ export class SupportService { if (!userData) throw new NotFoundException(`User not found`); // Load all related data in parallel - const [kycFiles, kycSteps, kycLogs, transactions, users, bankDatas, buyRoutes, sellRoutes] = await Promise.all([ - this.kycFileService.getUserDataKycFiles(id), - this.kycService.getStepsByUserData(id), - this.kycLogService.getLogsByUserDataId(id), - this.transactionService.getTransactionsByUserDataId(id), - this.userService.getAllUserDataUsers(id), - this.bankDataService.getBankDatasByUserData(id), - this.buyService.getUserDataBuys(id), - this.sellService.getSellsByUserDataId(id), + const [kycFiles, kycSteps, kycLogs, transactions, users, bankDatas, buyRoutes, sellRoutes, ipLogs, supportIssues] = + await Promise.all([ + this.kycFileService.getUserDataKycFiles(id), + this.kycService.getStepsByUserData(id), + this.kycLogService.getLogsByUserDataId(id), + this.transactionService.getTransactionsByUserDataId(id), + this.userService.getAllUserDataUsers(id), + this.bankDataService.getBankDatasByUserData(id), + this.buyService.getUserDataBuys(id), + this.sellService.getSellsByUserDataId(id), + this.ipLogService.getByUserDataId(id), + this.supportIssueService.getIssueEntities(id), + ]); + + // Load bank transactions for the loaded transactions (incoming + outgoing) + const transactionIds = transactions.map((t) => t.id); + const [incomingBankTxs, buyFiats, cryptoInputs] = await Promise.all([ + this.bankTxService.getBankTxsByTransactionIds(transactionIds), + this.buyFiatService.getBuyFiatsByTransactionIds(transactionIds), + this.payInService.getCryptoInputsByTransactionIds(transactionIds), ]); + // Merge incoming BankTx (direct) and outgoing BankTx (via BuyFiat -> FiatOutput -> BankTx) + const outgoingBankTxs = buyFiats + .filter((bf) => bf.fiatOutput?.bankTx) + .map((bf) => { + const bankTx = bf.fiatOutput.bankTx; + bankTx.transaction = bf.transaction; + return bankTx; + }); + const bankTxs = [...incomingBankTxs, ...outgoingBankTxs]; + // Load recommendation data for Recommendation steps const recommendationStepIds = kycSteps.filter((s) => s.name === KycStepName.RECOMMENDATION).map((s) => s.id); const recommendations = await this.recommendationService.getRecommendationsByKycStepIdsOrUserDataId( @@ -144,6 +176,10 @@ export class SupportService { ), kycLogs: kycLogs.map((l) => this.toKycLogSupportInfo(l)), transactions: transactions.map((t) => this.toTransactionSupportInfo(t)), + bankTxs: bankTxs.map((b) => this.toBankTxDto(b)), + cryptoInputs: cryptoInputs.map((c) => this.toCryptoInputSupportInfo(c)), + ipLogs: ipLogs.map((l) => this.toIpLogSupportInfo(l)), + supportIssues: supportIssues.map((s) => this.toSupportIssueSupportInfo(s)), users: users.map((u) => this.toUserSupportInfo(u)), bankDatas: bankDatas.map((b) => this.toBankDataSupportInfo(b)), buyRoutes: buyRoutes.map((b) => this.toBuySupportInfo(b)), @@ -294,6 +330,12 @@ export class SupportService { sourceType: tx.sourceType, amountInChf: tx.amountInChf, amlCheck: tx.amlCheck, + chargebackDate: + tx.buyCrypto?.chargebackDate ?? + tx.buyFiat?.chargebackDate ?? + tx.bankTxReturn?.chargebackDate ?? + tx.bankTxRepeat?.chargebackDate, + amlReason: tx.buyCrypto?.amlReason ?? tx.buyFiat?.amlReason, created: tx.created, }; } @@ -313,18 +355,26 @@ export class SupportService { id: bankData.id, iban: bankData.iban, name: bankData.name, + type: bankData.type, + status: bankData.status, approved: bankData.approved, + manualApproved: bankData.manualApproved, + active: bankData.active, + comment: bankData.comment, + created: bankData.created, }; } private toBuySupportInfo(buy: Buy): BuySupportInfo { return { id: buy.id, + iban: buy.iban, bankUsage: buy.bankUsage, assetName: buy.asset?.name, blockchain: buy.asset?.blockchain, volume: buy.volume, active: buy.active, + created: buy.created, }; } @@ -334,6 +384,8 @@ export class SupportService { iban: sell.iban, fiatName: sell.fiat?.name, volume: sell.annualVolume, + active: sell.active, + created: sell.created, }; } @@ -545,6 +597,72 @@ export class SupportService { type: bankTx.type, name: bankTx.completeName(), iban: bankTx.iban, + remittanceInfo: bankTx.remittanceInfo, + }; + } + + private toCryptoInputSupportInfo(ci: CryptoInput): CryptoInputSupportInfo { + const blockchain = ci.asset?.blockchain ?? ci.address?.blockchain; + return { + id: ci.id, + transactionId: ci.transaction?.id, + inTxId: ci.inTxId, + inTxExplorerUrl: blockchain ? txExplorerUrl(blockchain, ci.inTxId) : undefined, + status: ci.status, + amount: ci.amount, + assetName: ci.asset?.name, + blockchain, + senderAddresses: ci.senderAddresses, + returnTxId: ci.returnTxId, + returnTxExplorerUrl: blockchain && ci.returnTxId ? txExplorerUrl(blockchain, ci.returnTxId) : undefined, + purpose: ci.purpose, + }; + } + + private toIpLogSupportInfo(ipLog: IpLog): IpLogSupportInfo { + return { + id: ipLog.id, + ip: ipLog.ip, + country: ipLog.country, + url: ipLog.url, + result: ipLog.result, + created: ipLog.created, + }; + } + + private toSupportIssueSupportInfo(issue: SupportIssue): SupportIssueSupportInfo { + return { + id: issue.id, + uid: issue.uid, + type: issue.type, + state: issue.state, + reason: issue.reason, + name: issue.name, + clerk: issue.clerk, + department: issue.department, + information: issue.information, + messages: (issue.messages ?? []) + .sort((a, b) => b.created.getTime() - a.created.getTime()) + .map((m) => ({ author: m.author, message: m.message, created: m.created })), + transaction: issue.transaction + ? { + id: issue.transaction.id, + uid: issue.transaction.uid, + type: issue.transaction.type, + sourceType: issue.transaction.sourceType, + amountInChf: issue.transaction.amountInChf, + amlCheck: issue.transaction.amlCheck, + } + : undefined, + limitRequest: issue.limitRequest + ? { + limit: issue.limitRequest.limit, + acceptedLimit: issue.limitRequest.acceptedLimit, + decision: issue.limitRequest.decision, + fundOrigin: issue.limitRequest.fundOrigin, + } + : undefined, + created: issue.created, }; } diff --git a/src/subdomains/supporting/bank-tx/bank-tx/services/bank-tx.service.ts b/src/subdomains/supporting/bank-tx/bank-tx/services/bank-tx.service.ts index 9a928ab339..fe97de707e 100644 --- a/src/subdomains/supporting/bank-tx/bank-tx/services/bank-tx.service.ts +++ b/src/subdomains/supporting/bank-tx/bank-tx/services/bank-tx.service.ts @@ -408,6 +408,14 @@ export class BankTxService implements OnModuleInit { return this.bankTxRepo.findOne({ where: { transaction: { id: transactionId } }, relations }); } + async getBankTxsByTransactionIds(transactionIds: number[]): Promise { + if (!transactionIds.length) return []; + return this.bankTxRepo.find({ + where: { transaction: { id: In(transactionIds) } }, + relations: { transaction: true }, + }); + } + async getBankTxById(id: number, relations?: FindOptionsRelations): Promise { return this.bankTxRepo.findOne({ where: { id }, relations }); } diff --git a/src/subdomains/supporting/payin/services/payin.service.ts b/src/subdomains/supporting/payin/services/payin.service.ts index feb4fccbff..d535972f98 100644 --- a/src/subdomains/supporting/payin/services/payin.service.ts +++ b/src/subdomains/supporting/payin/services/payin.service.ts @@ -129,6 +129,14 @@ export class PayInService { return payIns; } + async getCryptoInputsByTransactionIds(transactionIds: number[]): Promise { + if (!transactionIds.length) return []; + return this.payInRepository.find({ + where: { transaction: { id: In(transactionIds) } }, + relations: { transaction: true }, + }); + } + async getCryptoInputByKeys(keys: string[], value: any): Promise { const query = this.payInRepository .createQueryBuilder('cryptoInput') diff --git a/src/subdomains/supporting/payment/services/transaction.service.ts b/src/subdomains/supporting/payment/services/transaction.service.ts index d10608ea92..5eba49db5b 100644 --- a/src/subdomains/supporting/payment/services/transaction.service.ts +++ b/src/subdomains/supporting/payment/services/transaction.service.ts @@ -125,6 +125,7 @@ export class TransactionService { async getTransactionsByUserDataId(userDataId: number): Promise { return this.repo.find({ where: { userData: { id: userDataId } }, + relations: { buyCrypto: true, buyFiat: true, bankTxReturn: true, bankTxRepeat: true }, order: { created: 'DESC' }, take: 100, }); diff --git a/src/subdomains/supporting/support-issue/services/support-issue.service.ts b/src/subdomains/supporting/support-issue/services/support-issue.service.ts index 94c73f310e..c609fdd9c4 100644 --- a/src/subdomains/supporting/support-issue/services/support-issue.service.ts +++ b/src/subdomains/supporting/support-issue/services/support-issue.service.ts @@ -210,6 +210,14 @@ export class SupportIssueService { return this.createMessageInternal(issue, dto); } + async getIssueEntities(userDataId: number): Promise { + return this.supportIssueRepo.find({ + where: { userData: { id: userDataId } }, + relations: { transaction: true, limitRequest: true, messages: true }, + order: { created: 'DESC' }, + }); + } + async getIssues(userDataId: number): Promise { const issues = await this.supportIssueRepo.find({ where: { userData: { id: userDataId } },