fix(api): resolve NestJS DI + ValidationPipe bugs from type-only imports

- Remove `type` modifier from imports used as DI constructor params
  across ~235 files (@Injectable, @Controller, @Module, @Catch,
  @CommandHandler, @QueryHandler, @EventsHandler, @WebSocketGateway).
  TypeScript emitDecoratorMetadata strips type-only imports, leaving
  Reflect.metadata with Function placeholder and breaking Nest DI.
- Fix controllers: DTOs used with @Body/@Query/@Param must be runtime
  imports so ValidationPipe can whitelist properties. Previously
  returned 400 "property X should not exist" on every request.
- Register ProjectsModule in AppModule (was defined but never wired).
- Add approve()/reject() methods to TransferListingEntity referenced by
  ModerateTransferListingHandler.
- Export BankTransferConfirmedEvent from payments barrel for
  subscription activation handler.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-04-18 21:50:30 +07:00
parent 4143c4dcb9
commit 312532b1cb
242 changed files with 460 additions and 442 deletions

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { type MarketIndex as PrismaMarketIndex, type PropertyType } from '@prisma/client';
import { type PrismaService } from '@modules/shared';
import { PrismaService } from '@modules/shared';
import { MarketIndexEntity, type MarketIndexProps } from '../../domain/entities/market-index.entity';
import {
type IMarketIndexRepository,

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { type Prisma, type Valuation as PrismaValuation } from '@prisma/client';
import { type PrismaService } from '@modules/shared';
import { PrismaService } from '@modules/shared';
import { ValuationEntity, type ValuationProps } from '../../domain/entities/valuation.entity';
import { type IValuationRepository } from '../../domain/repositories/valuation.repository';

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { type LoggerService } from '@modules/shared';
import { LoggerService } from '@modules/shared';
export interface AiPredictRequest {
area: number;

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { type PrismaService, type LoggerService } from '@modules/shared';
import { PrismaService, LoggerService } from '@modules/shared';
@Injectable()
export class AvmRetrainCronService {

View File

@@ -1,5 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import { type PrismaService, type LoggerService } from '@modules/shared';
import { PrismaService, LoggerService } from '@modules/shared';
import {
type IAVMService,
type AVMParams,
@@ -13,7 +13,7 @@ import {
type IAiServiceClient,
type AiPredictRequest,
} from './ai-service.client';
import { type PrismaAVMService } from './prisma-avm.service';
import { PrismaAVMService } from './prisma-avm.service';
/** Max concurrency for batch AI calls to avoid overloading the Python service. */
const BATCH_CONCURRENCY = 5;

View File

@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { type CommandBus } from '@nestjs/cqrs';
import { CommandBus } from '@nestjs/cqrs';
import { Cron, CronExpression } from '@nestjs/schedule';
import { PropertyType } from '@prisma/client';
import { type PrismaService, type LoggerService } from '@modules/shared';
import { PrismaService, LoggerService } from '@modules/shared';
import { UpdateMarketIndexCommand } from '../../application/commands/update-market-index/update-market-index.command';
interface MarketStats {

View File

@@ -1,6 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { POIType } from '@prisma/client';
import { type PrismaService, type LoggerService } from '@modules/shared';
import { PrismaService, LoggerService } from '@modules/shared';
import {
type INeighborhoodScoreService,
type NeighborhoodScoreResult,

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { type PropertyType } from '@prisma/client';
import { type PrismaService } from '@modules/shared';
import { PrismaService } from '@modules/shared';
import {
type IAVMService,
type AVMParams,