All files / subway subway.service.ts

100% Statements 33/33
100% Branches 1/1
100% Functions 8/8
100% Lines 31/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 885x 5x 5x 5x 5x 5x   5x 5x 5x 5x   5x 5x     5x   15x 15x                 1x         1x             1x 2x 4x   2x       1x                     1x       2x 2x 1x     1x     2x             1x   1x   2x          
import { Injectable, NotFoundException } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { PLACE_TYPE } from 'src/commons/enum/place-type-enum';
import { findCountByType } from 'src/commons/helpers/place-count-by-type.helper';
import { isEmpty } from 'src/commons/util/is/is-empty';
import { PlaceQueryRepository } from 'src/place/place.query.repository';
import { ApiSubwayGetCheckRequestQueryDto } from 'src/subway/dto/api-subway-get-check-request-query.dto';
import { ApiSubwayGetCheckResponseDto } from 'src/subway/dto/api-subway-get-check-response.dto';
import { ApiSubwayGetLineResponseDto } from 'src/subway/dto/api-subway-get-line-response.dto';
import { ApiSubwayGetListResponseDto } from 'src/subway/dto/api-subway-get-list-response.dto';
import { SubwayCustomListDto } from 'src/subway/dto/subway-custom-list.dto';
import { StationInfo } from 'src/subway/interfaces/subway.interfaces';
import { SubwayQueryRepository } from 'src/subway/subway.query.repository';
import { ERROR } from '../commons/constants/error';
 
@Injectable()
export class SubwayService {
  constructor(
    private readonly subwayQueryRepository: SubwayQueryRepository,
    private readonly placeQueryRepository: PlaceQueryRepository,
  ) {}
 
  async subwayCustomsCheck(
    lineUuid: string,
    stationUuid: string,
    dto: ApiSubwayGetCheckRequestQueryDto,
  ): Promise<ApiSubwayGetCheckResponseDto> {
    // 1. Retrieve station info first
    const stationInfo: StationInfo = await this.subwayQueryRepository.findLineAndStation(
      lineUuid,
      stationUuid,
    );
    // 2. 병렬로 호출 (customs, current culture, 이미 추가된 장소)
    const [subwayCustoms, subwayCurrentCulture, alreadyAddedPlaces] = await Promise.all([
      this.subwayQueryRepository.groupByCustoms(stationInfo),
      this.subwayQueryRepository.findSubwayCurrentCulture(stationInfo),
      this.placeQueryRepository.findPlacesWithUuids(dto.place_uuids),
    ]);
 
    // 3. Updated subway customs
    const updatedSubwayCustoms = subwayCustoms.map((custom) => {
      const addedCount = alreadyAddedPlaces.filter(
        (place) => place.place_type === custom.type,
      ).length;
      return { ...custom, count: Number(custom.count) - addedCount };
    });
 
    // 4. Compose customs check
    const customsCheck = new SubwayCustomListDto({
      RESTAURANT: findCountByType(PLACE_TYPE.RESTAURANT, updatedSubwayCustoms),
      CAFE: findCountByType(PLACE_TYPE.CAFE, updatedSubwayCustoms),
      BAR: findCountByType(PLACE_TYPE.BAR, updatedSubwayCustoms),
      SHOPPING: findCountByType(PLACE_TYPE.SHOPPING, updatedSubwayCustoms),
      CULTURE:
        findCountByType(PLACE_TYPE.EXHIBITION, subwayCurrentCulture) +
        findCountByType(PLACE_TYPE.POPUP, subwayCurrentCulture),
      ENTERTAINMENT: findCountByType(PLACE_TYPE.ENTERTAINMENT, updatedSubwayCustoms),
    });
 
    return new ApiSubwayGetCheckResponseDto({ items: customsCheck });
  }
 
  async subwayStationList(lineUuid: string): Promise<ApiSubwayGetListResponseDto> {
    const subwayStationList = await this.subwayQueryRepository.subwayStationList(lineUuid);
    if (isEmpty(subwayStationList)) {
      throw new NotFoundException(ERROR.NOT_EXIST_DATA);
    }
 
    return plainToInstance(
      ApiSubwayGetListResponseDto,
      {
        items: subwayStationList.map((station) => ({ uuid: station.uuid, station: station.name })),
      },
      { excludeExtraneousValues: true },
    );
  }
 
  async subwayLineList(): Promise<ApiSubwayGetLineResponseDto> {
    const subwayLine = await this.subwayQueryRepository.findSubwayLine();
 
    return plainToInstance(
      ApiSubwayGetLineResponseDto,
      { items: subwayLine.map((item) => ({ uuid: item.uuid, line: item.line })) },
      { excludeExtraneousValues: true },
    );
  }
}