fix(api,ci): remove type-only imports for DI and isolate CI ports from dev
- Remove `type` keyword from NestJS injectable class imports across all modules to fix runtime DI resolution (330+ handler/listener files) - Offset CI docker-compose ports (5433/6380/8109/9002) to avoid conflicts with running dev containers - Update .env.test, playwright.config.ts, and e2e workflow to use isolated CI ports with configurable overrides - Fix prisma/seed.ts to use deterministic IDs for Prisma 7 upsert compatibility (phoneHash replaced phone as unique index) - Add dedicated Docker bridge network for CI service containers Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
|
||||
export class GenerateReportCommand {
|
||||
constructor(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, type LoggerService } from '@modules/shared';
|
||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
MARKET_INDEX_REPOSITORY,
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
type MarketReportResult,
|
||||
} from '../../../domain/repositories/market-index.repository';
|
||||
import { GenerateReportCommand } from './generate-report.command';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { InternalServerErrorException } from '@nestjs/common';
|
||||
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, type LoggerService } from '@modules/shared';
|
||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, LoggerService } from '@modules/shared';
|
||||
import { TrackEventCommand } from './track-event.command';
|
||||
|
||||
export interface TrackEventResult {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
|
||||
export class UpdateMarketIndexCommand {
|
||||
constructor(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, type CacheService, CachePrefix, type LoggerService } from '@modules/shared';
|
||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, LoggerService } from '@modules/shared';
|
||||
import { MarketIndexEntity } from '../../../domain/entities/market-index.entity';
|
||||
import {
|
||||
MARKET_INDEX_REPOSITORY,
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
} from '../../../domain/repositories/market-index.repository';
|
||||
import { UpdateMarketIndexCommand } from './update-market-index.command';
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { EventsHandler, type IEventHandler, type CommandBus } from '@nestjs/cqrs';
|
||||
import { EventsHandler, IEventHandler, CommandBus } from '@nestjs/cqrs';
|
||||
import { ListingCreatedEvent, ModerateListingCommand } from '@modules/listings';
|
||||
import { type PrismaService, type LoggerService } from '@modules/shared';
|
||||
import { PrismaService, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
AI_SERVICE_CLIENT,
|
||||
type IAiServiceClient,
|
||||
IAiServiceClient,
|
||||
} from '../../infrastructure/services/ai-service.client';
|
||||
|
||||
const AUTO_REJECT_THRESHOLD = 0.8;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, type CacheService, CachePrefix, CacheTTL, Cacheable, type LoggerService } from '@modules/shared';
|
||||
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, Cacheable, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
MARKET_INDEX_REPOSITORY,
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
type DistrictStatsResult,
|
||||
} from '../../../domain/repositories/market-index.repository';
|
||||
import { GetDistrictStatsQuery } from './get-district-stats.query';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, type LoggerService } from '@modules/shared';
|
||||
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
MARKET_INDEX_REPOSITORY,
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
type HeatmapDataPoint,
|
||||
} from '../../../domain/repositories/market-index.repository';
|
||||
import { GetHeatmapQuery } from './get-heatmap.query';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, type LoggerService } from '@modules/shared';
|
||||
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
MARKET_INDEX_REPOSITORY,
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
type MarketReportResult,
|
||||
} from '../../../domain/repositories/market-index.repository';
|
||||
import { GetMarketReportQuery } from './get-market-report.query';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
|
||||
export class GetMarketReportQuery {
|
||||
constructor(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, type LoggerService } from '@modules/shared';
|
||||
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
MARKET_INDEX_REPOSITORY,
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
type PriceTrendPoint,
|
||||
} from '../../../domain/repositories/market-index.repository';
|
||||
import { GetPriceTrendQuery } from './get-price-trend.query';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
|
||||
export class GetPriceTrendQuery {
|
||||
constructor(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Inject, InternalServerErrorException } from '@nestjs/common';
|
||||
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, type LoggerService } from '@modules/shared';
|
||||
import { QueryHandler, IQueryHandler } from '@nestjs/cqrs';
|
||||
import { DomainException, CacheService, CachePrefix, CacheTTL, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
AVM_SERVICE,
|
||||
type IAVMService,
|
||||
IAVMService,
|
||||
type ValuationResult,
|
||||
} from '../../../domain/services/avm-service';
|
||||
import { GetValuationQuery } from './get-valuation.query';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
|
||||
export class GetValuationQuery {
|
||||
constructor(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
import { AggregateRoot } from '@modules/shared';
|
||||
import { MarketIndexUpdatedEvent } from '../events/market-index-updated.event';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type DomainEvent } from '@modules/shared';
|
||||
import { DomainEvent } from '@modules/shared';
|
||||
|
||||
export class MarketIndexUpdatedEvent implements DomainEvent {
|
||||
readonly eventName = 'market-index.updated';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export { MARKET_INDEX_REPOSITORY, type IMarketIndexRepository, type MarketReportResult, type HeatmapDataPoint, type PriceTrendPoint, type DistrictStatsResult } from './market-index.repository';
|
||||
export { VALUATION_REPOSITORY, type IValuationRepository } from './valuation.repository';
|
||||
export { MARKET_INDEX_REPOSITORY, IMarketIndexRepository, type MarketReportResult, type HeatmapDataPoint, type PriceTrendPoint, type DistrictStatsResult } from './market-index.repository';
|
||||
export { VALUATION_REPOSITORY, IValuationRepository } from './valuation.repository';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { type MarketIndexEntity } from '../entities/market-index.entity';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
import { MarketIndexEntity } from '../entities/market-index.entity';
|
||||
|
||||
export const MARKET_INDEX_REPOSITORY = Symbol('MARKET_INDEX_REPOSITORY');
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type ValuationEntity } from '../entities/valuation.entity';
|
||||
import { ValuationEntity } from '../entities/valuation.entity';
|
||||
|
||||
export const VALUATION_REPOSITORY = Symbol('VALUATION_REPOSITORY');
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
|
||||
export const AVM_SERVICE = Symbol('AVM_SERVICE');
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { AVM_SERVICE, type IAVMService, type AVMParams, type ValuationResult, type Comparable } from './avm-service';
|
||||
export { AVM_SERVICE, IAVMService, type AVMParams, type ValuationResult, type Comparable } from './avm-service';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { AnalyticsModule } from './analytics.module';
|
||||
export { MARKET_INDEX_REPOSITORY, type IMarketIndexRepository } from './domain/repositories/market-index.repository';
|
||||
export { VALUATION_REPOSITORY, type IValuationRepository } from './domain/repositories/valuation.repository';
|
||||
export { MARKET_INDEX_REPOSITORY, IMarketIndexRepository } from './domain/repositories/market-index.repository';
|
||||
export { VALUATION_REPOSITORY, IValuationRepository } from './domain/repositories/valuation.repository';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { type MarketIndex as PrismaMarketIndex, type PropertyType } from '@prisma/client';
|
||||
import { type PrismaService } from '@modules/shared';
|
||||
import { MarketIndexEntity, type MarketIndexProps } from '../../domain/entities/market-index.entity';
|
||||
import { MarketIndex as PrismaMarketIndex, PropertyType } from '@prisma/client';
|
||||
import { PrismaService } from '@modules/shared';
|
||||
import { MarketIndexEntity, MarketIndexProps } from '../../domain/entities/market-index.entity';
|
||||
import {
|
||||
type IMarketIndexRepository,
|
||||
IMarketIndexRepository,
|
||||
type MarketReportResult,
|
||||
type HeatmapDataPoint,
|
||||
type PriceTrendPoint,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { type Prisma, type Valuation as PrismaValuation } from '@prisma/client';
|
||||
import { type PrismaService } from '@modules/shared';
|
||||
import { ValuationEntity, type ValuationProps } from '../../domain/entities/valuation.entity';
|
||||
import { type IValuationRepository } from '../../domain/repositories/valuation.repository';
|
||||
import { Prisma, Valuation as PrismaValuation } from '@prisma/client';
|
||||
import { PrismaService } from '@modules/shared';
|
||||
import { ValuationEntity, ValuationProps } from '../../domain/entities/valuation.entity';
|
||||
import { IValuationRepository } from '../../domain/repositories/valuation.repository';
|
||||
|
||||
@Injectable()
|
||||
export class PrismaValuationRepository implements IValuationRepository {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { type Comparable } from '../../domain/services/avm-service';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
import { Comparable } from '../../domain/services/avm-service';
|
||||
|
||||
const DEFAULT_RADIUS_METERS = 2000;
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { type PrismaService, type LoggerService } from '@modules/shared';
|
||||
import { PrismaService, LoggerService } from '@modules/shared';
|
||||
import {
|
||||
type IAVMService,
|
||||
IAVMService,
|
||||
type AVMParams,
|
||||
type ValuationResult,
|
||||
type Comparable,
|
||||
} from '../../domain/services/avm-service';
|
||||
import {
|
||||
AI_SERVICE_CLIENT,
|
||||
type IAiServiceClient,
|
||||
IAiServiceClient,
|
||||
type AiPredictRequest,
|
||||
} from './ai-service.client';
|
||||
import { type PrismaAVMService } from './prisma-avm.service';
|
||||
import { PrismaAVMService } from './prisma-avm.service';
|
||||
|
||||
@Injectable()
|
||||
export class HttpAVMService implements IAVMService {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { type PropertyType } from '@prisma/client';
|
||||
import { type PrismaService } from '@modules/shared';
|
||||
import { PropertyType } from '@prisma/client';
|
||||
import { PrismaService } from '@modules/shared';
|
||||
import {
|
||||
type IAVMService,
|
||||
IAVMService,
|
||||
type AVMParams,
|
||||
type ValuationResult,
|
||||
type Comparable,
|
||||
|
||||
@@ -4,25 +4,25 @@ import {
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { type QueryBus } from '@nestjs/cqrs';
|
||||
import { QueryBus } from '@nestjs/cqrs';
|
||||
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from '@modules/auth';
|
||||
import { RequireQuota, QuotaGuard } from '@modules/subscriptions';
|
||||
import { type DistrictStatsDto } from '../../application/queries/get-district-stats/get-district-stats.handler';
|
||||
import { DistrictStatsDto } from '../../application/queries/get-district-stats/get-district-stats.handler';
|
||||
import { GetDistrictStatsQuery } from '../../application/queries/get-district-stats/get-district-stats.query';
|
||||
import { type HeatmapDto } from '../../application/queries/get-heatmap/get-heatmap.handler';
|
||||
import { HeatmapDto } from '../../application/queries/get-heatmap/get-heatmap.handler';
|
||||
import { GetHeatmapQuery } from '../../application/queries/get-heatmap/get-heatmap.query';
|
||||
import { type MarketReportDto } from '../../application/queries/get-market-report/get-market-report.handler';
|
||||
import { MarketReportDto } from '../../application/queries/get-market-report/get-market-report.handler';
|
||||
import { GetMarketReportQuery } from '../../application/queries/get-market-report/get-market-report.query';
|
||||
import { type PriceTrendDto } from '../../application/queries/get-price-trend/get-price-trend.handler';
|
||||
import { PriceTrendDto } from '../../application/queries/get-price-trend/get-price-trend.handler';
|
||||
import { GetPriceTrendQuery } from '../../application/queries/get-price-trend/get-price-trend.query';
|
||||
import { type ValuationDto } from '../../application/queries/get-valuation/get-valuation.handler';
|
||||
import { ValuationDto } from '../../application/queries/get-valuation/get-valuation.handler';
|
||||
import { GetValuationQuery } from '../../application/queries/get-valuation/get-valuation.query';
|
||||
import { type GetDistrictStatsDto } from '../dto/get-district-stats.dto';
|
||||
import { type GetHeatmapDto } from '../dto/get-heatmap.dto';
|
||||
import { type GetMarketReportDto } from '../dto/get-market-report.dto';
|
||||
import { type GetPriceTrendDto } from '../dto/get-price-trend.dto';
|
||||
import { type GetValuationDto } from '../dto/get-valuation.dto';
|
||||
import { GetDistrictStatsDto } from '../dto/get-district-stats.dto';
|
||||
import { GetHeatmapDto } from '../dto/get-heatmap.dto';
|
||||
import { GetMarketReportDto } from '../dto/get-market-report.dto';
|
||||
import { GetPriceTrendDto } from '../dto/get-price-trend.dto';
|
||||
import { GetValuationDto } from '../dto/get-valuation.dto';
|
||||
|
||||
@ApiTags('analytics')
|
||||
@Controller('analytics')
|
||||
|
||||
Reference in New Issue
Block a user