From 9d78816618048c4fca0146292bd610919c754d5b Mon Sep 17 00:00:00 2001 From: Blume1977 Date: Fri, 22 May 2026 11:25:23 +0200 Subject: [PATCH] fix(user): make getNextRef Postgres-compatible The `LIKE '%[0-9]-[0-9]%'` filter in UserRepository.getNextRef relied on MSSQL character-class syntax. On Postgres, `[0-9]` is a literal 5-char sequence, so the query matched no rows. findOne returned null and the chained `.then((u) => +u.ref.replace(...) + 1)` threw a TypeError every time setUserRef ran for a user without a ref on a userData with kycLevel >= 50. Since develop->main released the PSQL migration to prod, this has been crashing every caller of setUserRef: new user creation on KYC50+ userData, admin updateUser with setRef=true, KYC level bumps to >= 50, updatePersonalData on KYC50+ userData, and the mergeUserData activation loop. The merge case is especially visible because the V8 TypeError text reaches end users via ApiExceptionFilter and the DFX-Services frontend. Replace the MSSQL LIKE with a Postgres POSIX regex on the column, and guard the deref so a future empty-result state does not reintroduce the same crash shape. --- .../generic/user/models/user/user.repository.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/subdomains/generic/user/models/user/user.repository.ts b/src/subdomains/generic/user/models/user/user.repository.ts index f97896ec9e..367ec3524f 100644 --- a/src/subdomains/generic/user/models/user/user.repository.ts +++ b/src/subdomains/generic/user/models/user/user.repository.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { BaseRepository } from 'src/shared/repositories/base.repository'; import { Util } from 'src/shared/utils/util'; -import { EntityManager, Like } from 'typeorm'; +import { EntityManager, Raw } from 'typeorm'; import { KycLevel } from '../user-data/user-data.enum'; import { User } from './user.entity'; @@ -25,13 +25,16 @@ export class UserRepository extends BaseRepository { } private async getNextRef(): Promise { - // get highest numerical ref - const nextRef = await this.findOne({ + // get highest numerical ref — POSIX regex on the column is PG-compatible; + // the prior `LIKE '%[0-9]-[0-9]%'` form relied on MSSQL character classes + // and silently matched nothing on Postgres, leaving setUserRef to throw. + const user = await this.findOne({ select: { id: true, ref: true }, - where: { ref: Like('%[0-9]-[0-9]%') }, + where: { ref: Raw((alias) => `${alias} ~ '[0-9]-[0-9]'`) }, order: { ref: 'DESC' }, - }).then((u) => +u.ref.replace('-', '') + 1); + }); + const nextRef = user?.ref ? +user.ref.replace('-', '') + 1 : 1; const ref = nextRef.toString().padStart(6, '0'); return `${ref.slice(0, 3)}-${ref.slice(3, 6)}`; }