fix(issuer/user): fix TypeORM databaseName error in coupon join + wallet frozen column name
- Replace leftJoinAndMapOne(Issuer entity) with two-step query to avoid TypeORM
metadata lookup error ('Cannot read databaseName of undefined')
- Extract unique issuer IDs from coupon results, then batch-fetch issuers and attach
- Fix wallet entity: map frozenBalance to 'frozen' column (not 'frozen_balance')
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fa512dd2eb
commit
6f70d7a2c2
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository, DataSource } from 'typeorm';
|
||||
import { Repository, DataSource, In } from 'typeorm';
|
||||
import { Coupon, CouponStatus } from '../../domain/entities/coupon.entity';
|
||||
import { Issuer } from '../../domain/entities/issuer.entity';
|
||||
import {
|
||||
|
|
@ -61,8 +61,6 @@ export class CouponRepository implements ICouponRepository {
|
|||
const { category, status, search, issuerId, page, limit } = filters;
|
||||
const qb = this.repo.createQueryBuilder('c');
|
||||
|
||||
qb.leftJoinAndMapOne('c.issuer', Issuer, 'i', 'i.id = c.issuer_id');
|
||||
|
||||
if (status) qb.andWhere('c.status = :status', { status });
|
||||
if (issuerId) qb.andWhere('c.issuer_id = :issuerId', { issuerId });
|
||||
if (category) qb.andWhere('c.category = :category', { category });
|
||||
|
|
@ -76,23 +74,33 @@ export class CouponRepository implements ICouponRepository {
|
|||
.skip((page - 1) * limit)
|
||||
.take(limit);
|
||||
|
||||
return qb.getManyAndCount();
|
||||
const [coupons, total] = await qb.getManyAndCount();
|
||||
await this._attachIssuers(coupons);
|
||||
return [coupons, total];
|
||||
}
|
||||
|
||||
async findByOwnerWithIssuerJoin(userId: string, filters: CouponListFilters): Promise<[Coupon[], number]> {
|
||||
const { status, page, limit } = filters;
|
||||
const qb = this.repo.createQueryBuilder('c');
|
||||
|
||||
qb.leftJoinAndMapOne('c.issuer', Issuer, 'i', 'i.id = c.issuer_id');
|
||||
qb.andWhere('c.owner_user_id = :userId', { userId });
|
||||
|
||||
if (status) qb.andWhere('c.status = :status', { status });
|
||||
|
||||
qb.orderBy('c.created_at', 'DESC')
|
||||
.skip((page - 1) * limit)
|
||||
.take(limit);
|
||||
|
||||
return qb.getManyAndCount();
|
||||
const [coupons, total] = await qb.getManyAndCount();
|
||||
await this._attachIssuers(coupons);
|
||||
return [coupons, total];
|
||||
}
|
||||
|
||||
private async _attachIssuers(coupons: Coupon[]): Promise<void> {
|
||||
if (coupons.length === 0) return;
|
||||
const issuerIds = [...new Set(coupons.map((c) => c.issuerId))];
|
||||
const issuers = await this.dataSource.getRepository(Issuer).findBy({ id: In(issuerIds) });
|
||||
const issuerMap = new Map(issuers.map((i) => [i.id, i]));
|
||||
coupons.forEach((c) => { c.issuer = issuerMap.get(c.issuerId); });
|
||||
}
|
||||
|
||||
async getOwnerSummary(userId: string): Promise<OwnerSummary> {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export class Wallet {
|
|||
@PrimaryGeneratedColumn('uuid') id: string;
|
||||
@Column({ name: 'user_id', type: 'uuid', unique: true }) userId: string;
|
||||
@Column({ type: 'numeric', precision: 20, scale: 8, default: '0' }) balance: string;
|
||||
@Column({ name: 'frozen_balance', type: 'numeric', precision: 20, scale: 8, default: '0' }) frozenBalance: string;
|
||||
@Column({ name: 'frozen', type: 'numeric', precision: 20, scale: 8, default: '0' }) frozenBalance: string;
|
||||
@Column({ type: 'varchar', length: 10, default: 'USD' }) currency: string;
|
||||
@Column({ type: 'varchar', length: 20, default: 'active' }) status: string;
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' }) createdAt: Date;
|
||||
|
|
|
|||
Loading…
Reference in New Issue