diff --git a/packages/services/auth-service/src/application/services/auth.service.ts b/packages/services/auth-service/src/application/services/auth.service.ts index da533de..e5944a1 100644 --- a/packages/services/auth-service/src/application/services/auth.service.ts +++ b/packages/services/auth-service/src/application/services/auth.service.ts @@ -75,9 +75,8 @@ export class AuthService { if (!fallbackRows.length) throw new UnauthorizedException('Invalid credentials'); rows.push(...fallbackRows); } - const rawUser = rows[0]; - const user = Object.assign(new User(), rawUser) as User; - if (!user || !user.isActive) { + const user = this.mapRow(rows[0]); + if (!user.isActive) { throw new UnauthorizedException('Invalid credentials'); } @@ -86,8 +85,10 @@ export class AuthService { throw new UnauthorizedException('Invalid credentials'); } - user.lastLoginAt = new Date(); - await this.userRepository.save(user); + // Update last_login_at directly to avoid search_path issues + await this.dataSource.query( + `UPDATE public.users SET last_login_at = NOW() WHERE id = $1`, [user.id], + ); const tokens = this.generateTokens(user); @@ -484,9 +485,7 @@ export class AuthService { if (!rows.length) { throw new UnauthorizedException('User not found or inactive'); } - const user = Object.assign(new User(), rows[0]) as User; - - return this.generateTokens(user); + return this.generateTokens(this.mapRow(rows[0])); } async createApiKey( @@ -539,4 +538,21 @@ export class AuthService { return { accessToken, refreshToken }; } + + /** Map raw SQL row (snake_case) to User entity (camelCase) */ + private mapRow(raw: Record): User { + const u = new User(); + u.id = raw.id; + u.tenantId = raw.tenant_id; + u.email = raw.email ?? undefined; + u.phone = raw.phone ?? undefined; + u.passwordHash = raw.password_hash; + u.name = raw.name; + u.roles = raw.roles; + u.isActive = raw.is_active; + u.lastLoginAt = raw.last_login_at; + u.createdAt = raw.created_at; + u.updatedAt = raw.updated_at; + return u; + } }