Skip to content

Commit 5fa6a7c

Browse files
authored
Merge pull request #3156 from DFXswiss/develop
Release: develop -> main
2 parents 7e3a379 + e255e9f commit 5fa6a7c

3 files changed

Lines changed: 247 additions & 1 deletion

File tree

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/**
2+
* @typedef {import('typeorm').MigrationInterface} MigrationInterface
3+
* @typedef {import('typeorm').QueryRunner} QueryRunner
4+
*/
5+
6+
/**
7+
* Sync transaction AML data for 114 CryptoCrypto BuyCrypto records.
8+
*
9+
* Same root cause as migration 1768900000000-SyncTransactionAmlData:
10+
* BuyCrypto was completed (isComplete=true) before postProcessing could
11+
* set the transaction-level fields. All 115 records have bc.amlCheck='Pass'
12+
* but t.amlCheck/eventDate/amountInChf/assets are NULL.
13+
*
14+
* TX 278332 excluded: stuck PaymentLink transaction (isConfirmed=false, status=Created).
15+
*
16+
* All affected transactions:
17+
* - Account: userDataId 259962 (KycFile 3767)
18+
* - Created: 2025-12-30, batch-completed: 2025-12-31
19+
* - Type: CryptoCrypto (all output to BTC)
20+
* - Total volume: ~1,536 CHF (excl. TX 278332 which is stuck in Created status)
21+
*
22+
* @class
23+
* @implements {MigrationInterface}
24+
*/
25+
module.exports = class SyncCryptoCryptoTransactionAmlData1770500000000 {
26+
name = 'SyncCryptoCryptoTransactionAmlData1770500000000';
27+
28+
/**
29+
* @param {QueryRunner} queryRunner
30+
*/
31+
async up(queryRunner) {
32+
// Hardcoded transaction data from production DB query (2026-02-06)
33+
// Format: [txId, amountInChf (null if unknown), assets, eventDate]
34+
const transactions = [
35+
[261949, 0.86, 'BTC-BTC', '2025-12-30T08:41:15.583Z'],
36+
[261950, 1.72, 'BTC-BTC', '2025-12-30T14:08:50.550Z'],
37+
[262020, 2.16, 'XMR-BTC', '2025-12-30T14:08:30.266Z'],
38+
[262028, 7.18, 'XMR-BTC', '2025-12-30T14:08:33.106Z'],
39+
[262143, 2.05, 'XMR-BTC', '2025-12-30T14:08:32.363Z'],
40+
[262335, 50.55, 'BTC-BTC', '2025-12-30T14:08:31.646Z'],
41+
[262746, 5.77, 'BTC-BTC', '2025-12-30T14:08:30.973Z'],
42+
[263544, 42.8, 'BTC-BTC', '2025-12-30T14:08:43.990Z'],
43+
[263545, 18.87, 'BTC-BTC', '2025-12-30T14:08:38.496Z'],
44+
[264117, 18.27, 'BTC-BTC', '2025-12-30T14:08:52.546Z'],
45+
[264418, 15.73, 'BTC-BTC', '2025-12-30T14:09:10.426Z'],
46+
[264422, 41.4, 'BTC-BTC', '2025-12-30T14:09:03.110Z'],
47+
[267046, 22.71, 'BTC-BTC', '2025-12-30T14:08:34.233Z'],
48+
[267066, 11.65, 'BTC-BTC', '2025-12-30T14:08:58.240Z'],
49+
[267161, 14.94, 'BTC-BTC', '2025-12-30T14:09:00.486Z'],
50+
[267162, 10.32, 'BTC-BTC', '2025-12-30T14:08:35.756Z'],
51+
[267170, 26.01, 'BTC-BTC', '2025-12-30T14:08:55.476Z'],
52+
[267911, 3.79, 'BTC-BTC', '2025-12-30T14:09:23.390Z'],
53+
[268141, 10.42, 'BTC-BTC', '2025-12-30T14:09:16.463Z'],
54+
[268507, 7.14, 'BTC-BTC', '2025-12-30T14:09:17.243Z'],
55+
[268887, 7.39, 'BTC-BTC', '2025-12-30T14:09:08.140Z'],
56+
[269574, 1.73, 'USDT-BTC', '2025-12-30T14:09:12.926Z'],
57+
[271252, 2.1, 'BTC-BTC', '2025-12-30T14:09:18.140Z'],
58+
[271665, 36.98, 'BTC-BTC', '2025-12-30T14:09:24.270Z'],
59+
[271670, 1.65, 'USDT-BTC', '2025-12-30T14:09:18.883Z'],
60+
[272117, 15.04, 'USDT-BTC', '2025-12-30T14:09:19.140Z'],
61+
[273008, 2.51, 'XMR-BTC', '2025-12-30T14:09:15.356Z'],
62+
[273105, 8.43, 'BTC-BTC', '2025-12-30T14:09:13.386Z'],
63+
[273395, 23.57, 'BTC-BTC', '2025-12-30T14:08:52.906Z'],
64+
[273417, 5.68, 'XMR-BTC', '2025-12-30T14:08:58.633Z'],
65+
[273464, 40.26, 'BTC-BTC', '2025-12-30T14:09:21.756Z'],
66+
[273724, 8.27, 'BTC-BTC', '2025-12-30T14:09:11.770Z'],
67+
[273793, 1.06, 'USDT-BTC', '2025-12-30T14:09:09.263Z'],
68+
[274027, 19.04, 'BTC-BTC', '2025-12-30T14:09:02.880Z'],
69+
[274062, 2.64, 'BTC-BTC', '2025-12-30T14:08:59.423Z'],
70+
[274075, 22.13, 'BTC-BTC', '2025-12-30T14:09:09.583Z'],
71+
[274303, 3.57, 'BTC-BTC', '2025-12-30T14:08:53.306Z'],
72+
[274360, 10.75, 'USDT-BTC', '2025-12-30T14:08:58.990Z'],
73+
[274625, 5.41, 'USDT-BTC', '2025-12-30T14:09:22.010Z'],
74+
[274626, 13.63, 'USDT-BTC', '2025-12-30T14:09:12.246Z'],
75+
[274657, 3.45, 'BTC-BTC', '2025-12-30T14:09:10.126Z'],
76+
[274964, 9.74, 'BTC-BTC', '2025-12-30T14:08:29.593Z'],
77+
[275078, 15.74, 'BTC-BTC', '2025-12-30T14:08:44.456Z'],
78+
[275079, 19.24, 'BTC-BTC', '2025-12-30T14:08:50.960Z'],
79+
[275274, 10.74, 'BTC-BTC', '2025-12-30T14:08:30.643Z'],
80+
[275295, 3.1, 'BTC-BTC', '2025-12-30T14:08:33.460Z'],
81+
[275367, 15.56, 'USDT-BTC', '2025-12-30T14:08:32.766Z'],
82+
[275385, 1.55, 'BTC-BTC', '2025-12-30T14:08:32.040Z'],
83+
[275386, 15.47, 'USDT-BTC', '2025-12-30T14:08:31.316Z'],
84+
[275388, 9.43, 'BTC-BTC', '2025-12-30T14:08:29.896Z'],
85+
[275555, 1.55, 'BTC-BTC', '2025-12-30T14:08:49.826Z'],
86+
[275622, 8.63, 'BTC-BTC', '2025-12-30T14:09:00.223Z'],
87+
[275650, 1.53, 'BTC-BTC', '2025-12-30T14:08:34.576Z'],
88+
[275669, 9.32, 'USDT-BTC', '2025-12-30T14:08:54.396Z'],
89+
[275692, 1.51, 'BTC-BTC', '2025-12-30T14:08:53.680Z'],
90+
[275838, 31.86, 'BTC-BTC', '2025-12-30T14:08:38.976Z'],
91+
[275872, 3.05, 'BTC-BTC', '2025-12-30T14:08:37.966Z'],
92+
[275932, 8.13, 'BTC-BTC', '2025-12-30T14:08:33.813Z'],
93+
[275943, 11.4, 'BTC-BTC', '2025-12-30T14:08:57.580Z'],
94+
[276247, 13.92, 'BTC-BTC', '2025-12-30T14:09:19.453Z'],
95+
[276249, 6.8, 'BTC-BTC', '2025-12-30T14:09:01.566Z'],
96+
[276257, 21.46, 'BTC-BTC', '2025-12-30T14:09:03.703Z'],
97+
[276464, 3.16, 'BTC-BTC', '2025-12-30T14:09:22.546Z'],
98+
[276726, 11.66, 'BTC-BTC', '2025-12-30T14:09:16.210Z'],
99+
[276963, 11.99, 'BTC-BTC', '2025-12-30T14:09:15.980Z'],
100+
[277199, 1.61, 'BTC-BTC', '2025-12-30T14:09:07.830Z'],
101+
[277200, 9.44, 'BTC-BTC', '2025-12-30T14:09:02.636Z'],
102+
[277244, 9.64, 'BTC-BTC', '2025-12-30T14:09:19.723Z'],
103+
[277563, 13.62, 'BTC-BTC', '2025-12-30T14:09:04.803Z'],
104+
[277694, 6.74, 'BTC-BTC', '2025-12-30T14:09:19.960Z'],
105+
[277784, 3.61, 'BTC-BTC', '2025-12-30T14:09:01.870Z'],
106+
[277785, 12.78, 'BTC-BTC', '2025-12-30T14:09:14.280Z'],
107+
[277786, 28.41, 'BTC-BTC', '2025-12-30T14:09:22.850Z'],
108+
[277993, 9.03, 'BTC-BTC', '2025-12-30T14:08:56.210Z'],
109+
[278009, 3.02, 'BTC-BTC', '2025-12-30T14:08:51.383Z'],
110+
[278078, 2.46, 'BTC-BTC', '2025-12-30T14:09:00.743Z'],
111+
[278165, 3.35, 'BTC-BTC', '2025-12-30T14:09:05.253Z'],
112+
[278346, 9.04, 'BTC-BTC', '2025-12-30T14:09:02.110Z'],
113+
[278381, 5.02, 'BTC-BTC', '2025-12-30T14:09:14.563Z'],
114+
[278392, 6.24, 'BTC-BTC', '2025-12-30T14:09:23.136Z'],
115+
[278719, 1.43, 'BTC-BTC', '2025-12-30T14:08:56.830Z'],
116+
[279171, 10.11, 'USDT-BTC', '2025-12-30T14:08:51.740Z'],
117+
[279375, 3.11, 'BTC-BTC', '2025-12-30T14:09:00.990Z'],
118+
[280273, 20.76, 'BTC-BTC', '2025-12-30T14:08:54.060Z'],
119+
[280332, 21.15, 'BTC-BTC', '2025-12-30T14:09:10.706Z'],
120+
[281625, 6.97, 'BTC-BTC', '2025-12-30T14:09:08.863Z'],
121+
[281751, 8.82, 'BTC-BTC', '2025-12-30T14:08:52.146Z'],
122+
[282365, 8.5, 'BTC-BTC', '2025-12-30T14:08:59.890Z'],
123+
[282608, 24.19, 'BTC-BTC', '2025-12-30T14:09:09.870Z'],
124+
[283945, 28.6, 'BTC-BTC', '2025-12-30T14:09:01.290Z'],
125+
[283977, 0.9, 'BTC-BTC', '2025-12-30T14:09:03.360Z'],
126+
[284056, 10.75, 'BTC-BTC', '2025-12-30T14:09:22.283Z'],
127+
[284208, 20.36, 'BTC-BTC', '2025-12-30T14:09:12.606Z'],
128+
[284209, 14.45, 'BTC-BTC', '2025-12-30T14:09:15.733Z'],
129+
[284453, 9.48, 'USDT-BTC', '2025-12-30T14:09:07.546Z'],
130+
[284460, 10.23, 'USDT-BTC', '2025-12-30T14:09:02.366Z'],
131+
[284791, 22.94, 'BTC-BTC', '2025-12-30T14:09:06.803Z'],
132+
[284874, 7.49, 'BTC-BTC', '2025-12-30T14:09:20.566Z'],
133+
[284876, 10.36, 'BTC-BTC', '2025-12-30T14:09:13.753Z'],
134+
[285012, 27.13, 'BTC-BTC', '2025-12-30T14:09:16.726Z'],
135+
[285085, 6.57, 'BTC-BTC', '2025-12-30T14:09:23.676Z'],
136+
[285169, 37.02, 'BTC-BTC', '2025-12-30T14:09:18.640Z'],
137+
[285420, 31.06, 'BTC-BTC', '2025-12-30T14:09:17.516Z'],
138+
[285461, 6.81, 'BTC-BTC', '2025-12-30T14:09:08.390Z'],
139+
[285583, 31.95, 'BTC-BTC', '2025-12-30T14:09:07.103Z'],
140+
[285667, 6.45, 'BTC-BTC', '2025-12-30T14:09:20.973Z'],
141+
[286099, 30.99, 'BTC-BTC', '2025-12-30T14:09:13.986Z'],
142+
[286517, 16.24, 'BTC-BTC', '2025-12-30T14:09:16.980Z'],
143+
[286708, 31.16, 'BTC-BTC', '2025-12-30T14:09:23.963Z'],
144+
[287341, 22.64, 'BTC-BTC', '2025-12-30T14:09:21.233Z'],
145+
[288951, 28.7, 'BTC-BTC', '2025-12-30T14:09:14.820Z'],
146+
[289695, 23.74, 'BTC-BTC', '2025-12-30T14:09:17.770Z'],
147+
[290951, 45.64, 'BTC-BTC', '2025-12-30T14:09:21.493Z'],
148+
[292062, 29.3, 'BTC-BTC', '2025-12-30T14:09:15.080Z'],
149+
];
150+
151+
console.log('=== Sync CryptoCrypto Transaction AML Data ===\n');
152+
console.log(`Transactions to fix: ${transactions.length}`);
153+
154+
// Verify current state - all should have NULL amlCheck
155+
const currentState = await queryRunner.query(`
156+
SELECT COUNT(*) as count
157+
FROM dbo.[transaction]
158+
WHERE id IN (${transactions.map((t) => t[0]).join(',')})
159+
AND amlCheck IS NULL
160+
`);
161+
162+
const nullCount = currentState[0].count;
163+
console.log(`Verified: ${nullCount}/${transactions.length} have amlCheck=NULL\n`);
164+
165+
if (nullCount !== transactions.length) {
166+
const alreadyFixed = await queryRunner.query(`
167+
SELECT id, amlCheck
168+
FROM dbo.[transaction]
169+
WHERE id IN (${transactions.map((t) => t[0]).join(',')})
170+
AND amlCheck IS NOT NULL
171+
`);
172+
console.log(`WARNING: ${alreadyFixed.length} transactions already have amlCheck set:`);
173+
for (const tx of alreadyFixed) {
174+
console.log(` - Transaction ${tx.id}: amlCheck=${tx.amlCheck}`);
175+
}
176+
}
177+
178+
// Update each transaction with hardcoded values
179+
let updated = 0;
180+
181+
for (const [txId, amountInChf, assets, eventDate] of transactions) {
182+
const result = await queryRunner.query(
183+
`
184+
UPDATE dbo.[transaction]
185+
SET
186+
amlCheck = 'Pass',
187+
assets = '${assets}',
188+
amountInChf = ${amountInChf === null ? 'NULL' : amountInChf},
189+
highRisk = 0,
190+
eventDate = '${eventDate}',
191+
amlType = 'CryptoCrypto',
192+
updated = GETDATE()
193+
WHERE id = ${txId}
194+
AND amlCheck IS NULL
195+
`,
196+
);
197+
198+
if (result?.rowsAffected?.[0] > 0) updated++;
199+
}
200+
201+
console.log(`Updated ${updated}/${transactions.length} transactions\n`);
202+
203+
// Verify final state
204+
const finalState = await queryRunner.query(`
205+
SELECT COUNT(*) as count, SUM(amountInChf) as totalChf
206+
FROM dbo.[transaction]
207+
WHERE id IN (${transactions.map((t) => t[0]).join(',')})
208+
AND amlCheck = 'Pass'
209+
`);
210+
211+
console.log(`=== Verification ===`);
212+
console.log(` Transactions with amlCheck=Pass: ${finalState[0].count}`);
213+
console.log(` Total volume: ${finalState[0].totalChf} CHF`);
214+
}
215+
216+
/**
217+
* @param {QueryRunner} queryRunner
218+
*/
219+
async down(queryRunner) {
220+
const txIds = [
221+
261949, 261950, 262020, 262028, 262143, 262335, 262746, 263544, 263545, 264117, 264418, 264422, 267046, 267066,
222+
267161, 267162, 267170, 267911, 268141, 268507, 268887, 269574, 271252, 271665, 271670, 272117, 273008, 273105,
223+
273395, 273417, 273464, 273724, 273793, 274027, 274062, 274075, 274303, 274360, 274625, 274626, 274657, 274964,
224+
275078, 275079, 275274, 275295, 275367, 275385, 275386, 275388, 275555, 275622, 275650, 275669, 275692, 275838,
225+
275872, 275932, 275943, 276247, 276249, 276257, 276464, 276726, 276963, 277199, 277200, 277244, 277563, 277694,
226+
277784, 277785, 277786, 277993, 278009, 278078, 278165, 278346, 278381, 278392, 278719, 279171, 279375, 280273,
227+
280332, 281625, 281751, 282365, 282608, 283945, 283977, 284056, 284208, 284209, 284453, 284460, 284791, 284874,
228+
284876, 285012, 285085, 285169, 285420, 285461, 285583, 285667, 286099, 286517, 286708, 287341, 288951, 289695,
229+
290951, 292062,
230+
];
231+
232+
await queryRunner.query(`
233+
UPDATE dbo.[transaction]
234+
SET
235+
amlCheck = NULL,
236+
assets = NULL,
237+
amountInChf = NULL,
238+
highRisk = NULL,
239+
eventDate = NULL,
240+
amlType = NULL,
241+
updated = GETDATE()
242+
WHERE id IN (${txIds.join(',')})
243+
`);
244+
}
245+
};

src/subdomains/generic/support/support.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ export class SupportService {
176176
accountId: tx.userData?.id,
177177
kycFileId: tx.userData?.kycFileId,
178178
name: tx.userData?.verifiedName,
179-
domicile: tx.userData?.country?.name,
179+
domicile: tx.userData?.country?.name ?? tx.userData?.verifiedCountry?.name,
180180
created: tx.created,
181181
eventDate: tx.eventDate,
182182
outputDate: tx.outputDate,

src/subdomains/supporting/payment/services/transaction.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export class TransactionService {
135135
.select('transaction')
136136
.leftJoinAndSelect('transaction.userData', 'userData')
137137
.leftJoinAndSelect('userData.country', 'country')
138+
.leftJoinAndSelect('userData.verifiedCountry', 'verifiedCountry')
138139
.where('transaction.type IS NOT NULL');
139140

140141
if (dateFrom || dateTo || outputFrom || outputTo) {

0 commit comments

Comments
 (0)