Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Siwonpada/issue143 #147

Merged
merged 10 commits into from
Jan 19, 2025
Merged

Siwonpada/issue143 #147

merged 10 commits into from
Jan 19, 2025

Conversation

siwonpada
Copy link
Member

@siwonpada siwonpada commented Jan 16, 2025

Pull request

개요

PR Checklist

  • 환경에 따른 실행 여부를 확인하였나요?
  • 변경 내용에 관한 테스트를 진행하였나요?

Summary by CodeRabbit

여기 주요 릴리즈 노트입니다:

  • 새로운 기능

    • 크롤러 애플리케이션 추가
    • 공지사항 검색 시 대소문자 구분 없는 검색 지원
  • 개선 사항

    • 프로젝트 구조 재구성
    • 모듈 및 서비스 경로 최적화
    • API 컨트롤러 및 모듈 이름 업데이트
  • 기술적 변경

    • NestJS 모노레포 구조 도입
    • Docker 빌드 프로세스 최적화
    • TypeScript 설정 파일 업데이트
  • 버그 수정

    • 가져오기(import) 경로 문제 해결

Copy link

coderabbitai bot commented Jan 16, 2025

📝 Walkthrough

개요

Walkthrough

이 풀 리퀘스트는 프로젝트의 구조를 재구성하고 여러 애플리케이션을 지원하는 모노레포 설정을 도입했습니다. 주요 변경 사항은 apps 디렉토리 내에 apicrawler 애플리케이션을 추가하고, 가져오기 경로를 상대 경로로 업데이트하며, 빌드 및 배포 스크립트를 조정하는 것을 포함합니다. 새로운 크롤러 서비스는 공지 데이터를 가져오고 처리하는 기능을 추가했습니다.

Changes

파일 변경 요약
.github/workflows/* 워크플로우 경로 및 Dockerfile 위치 업데이트
.vscode/settings.json 맞춤법 검사 단어 목록 업데이트
apps/api/src/* 가져오기 경로 상대 경로로 변경, 컨트롤러 및 모듈 이름 업데이트
apps/crawler/* 새로운 크롤러 애플리케이션 추가 (서비스, 리포지토리, 모듈 등)
nest-cli.json 모노레포 구성 및 프로젝트 설정 업데이트
package.json 스크립트 및 종속성 업데이트

Poem

🐰 코드의 숲속, 새로운 길을 찾아서
모노레포의 토끼굴 문을 열었네
API와 크롤러, 함께 춤추는 서비스
상대 경로로 이어진 모듈의 노래
더 나은 코드, 더 즐거운 개발! 🚀

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (14)
apps/api/src/image/image.service.ts (1)

Line range hint 45-47: 이미지 형식 검증 로직 추가를 제안드립니다.

uploadImage 메서드에서 파일 확장자 검증 로직을 추가하면 좋을 것 같습니다. 허용된 이미지 형식만 처리하도록 하여 보안성을 향상시킬 수 있습니다.

  private async uploadImage(file: Express.Multer.File): Promise<string> {
+   const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif'];
+   const fileExtension = path.extname(file.originalname).toLowerCase();
+   if (!allowedExtensions.includes(fileExtension)) {
+     throw new BadRequestException('지원하지 않는 이미지 형식입니다.');
+   }
    const key = `${new Date().toISOString()}-${Math.random().toString(36).substring(2)}.${path.extname(file.originalname)}`;
    return this.fileService.uploadFile(await this.convertToWebp(file), key);
  }
apps/crawler/src/user/user.repository.ts (1)

10-14: 데이터베이스 성능 최적화 필요

name 필드에 대한 조회가 자주 발생할 것으로 예상되므로, 데이터베이스 인덱스 추가를 고려해주세요.

schema.prisma 파일에 다음과 같이 인덱스를 추가하는 것을 추천드립니다:

model User {
  // ... 기존 필드들
  
  @@index([name])
}
apps/api/src/notice/notice.repository.ts (2)

64-65: 검색 기능이 대소문자를 구분하지 않도록 개선되었습니다.

제목과 본문 검색에 대소문자 구분 없이 검색할 수 있도록 개선된 것이 좋습니다.

데이터베이스 성능 최적화를 위해 title과 body 컬럼에 case-insensitive 인덱스 추가를 고려해보세요:

CREATE INDEX idx_crawls_title_body ON crawls USING gin (lower(title) gin_trgm_ops, lower(body) gin_trgm_ops);
CREATE INDEX idx_contents_title_body ON contents USING gin (lower(title) gin_trgm_ops, lower(body) gin_trgm_ops);

Also applies to: 74-75


143-144: getNoticeList 메서드에도 동일한 대소문자 구분 없는 검색이 적용되었습니다.

getTotalCount와 getNoticeList 메서드 간에 검색 로직이 일관되게 구현되어 있습니다.

검색 조건 로직이 두 메서드에서 중복되므로, 공통 메서드로 분리하는 것을 고려해보세요:

+private getSearchCondition(search: string) {
+  return search
+    ? {
+        OR: [
+          {
+            crawls: {
+              some: {
+                OR: [
+                  { title: { contains: search, mode: 'insensitive' } },
+                  { body: { contains: search, mode: 'insensitive' } },
+                ],
+              },
+            },
+          },
+          {
+            contents: {
+              some: {
+                OR: [
+                  { title: { contains: search, mode: 'insensitive' } },
+                  { body: { contains: search, mode: 'insensitive' } },
+                ],
+              },
+            },
+          },
+          {
+            tags: {
+              some: { name: { contains: search, mode: 'insensitive' } },
+            },
+          },
+        ],
+      }
+    : {};
+}

Also applies to: 153-154, 159-163

apps/crawler/src/main.ts (3)

6-6: 불필요한 identity 임포트 제거

identity 함수는 이 코드에서 사용되지 않으므로 임포트를 제거하여 코드를 정리할 수 있습니다.

 import {
   concatMap,
   firstValueFrom,
-  identity,
   map,
   take,
   timeout,
   toArray,
 } from 'rxjs';

23-38: 오류 처리를 추가하여 안정성 향상

getNoticeList()와 그 후속 스트림에서 발생할 수 있는 오류를 캐치하지 않고 있습니다. 스트림에 catchError 연산자를 추가하여 오류 발생 시 적절한 처리를 할 수 있습니다.

             toArray(),
+          ),
+          catchError((error) => {
+            // 오류 로깅 또는 처리 로직 추가
+            console.error('오류 발생:', error);
+            return [];
           ),
         ),

46-60: newNotices 처리에서 예외 상황에 대한 오류 처리 필요

newNotices 처리 중 createCrawl 실행 시 발생할 수 있는 예외 상황에 대비하여 오류 처리가 필요합니다. 각 비동기 처리 내에 try-catch 블록을 추가하여 오류를 캐치하고 로깅할 수 있습니다.

       await Promise.all(
         newNotices.map(async ({ notice }) => {
+          try {
             await app.get(CrawlerService).createCrawl(
               {
                 title: notice.meta.title,
                 body: notice.notice.content ?? '',
                 type: 'ACADEMIC',
                 url: notice.meta.link,
                 crawledAt: new Date(),
               },
               new Date(notice.meta.createdAt),
               notice.meta.author,
             );
+          } catch (error) {
+            // 오류 로깅 또는 처리 로직 추가
+            console.error('createCrawl 오류 발생:', error);
+          }
         }),
       );
apps/crawler/src/crawler.service.ts (2)

55-74: HTTP 요청 실패 시 적절한 오류 처리 필요

getNoticeList() 메서드에서 HTTP 요청 실패나 파싱 오류가 발생할 경우를 대비하여 더 자세한 오류 처리가 필요합니다. catchError 연산자를 활용하여 사용자 정의 오류 메시지를 제공하거나 재시도 로직을 추가할 수 있습니다.

         return this.httpService.get(this.targetUrl).pipe(
           timeout(10 * 1000),
-          catchError(throwError),
+          catchError((error) => {
+            // 오류 로깅 또는 사용자 정의 오류 반환
+            console.error('공지 사항 리스트 가져오기 실패:', error);
+            return throwError(() => new Error('공지 사항 리스트를 가져오는 중 오류가 발생했습니다.'));
+          }),
           map((res) => load(res.data)),
           map(($) => $('table > tbody > tr')),
           concatMap(($) => $.toArray().map((value: any) => load(value))),
           map(($) => {
             return {
               title: $('td').eq(2).text().trim(),
               link: `${this.targetUrl}${$('td').eq(2).find('a').attr('href')}`,
               author: $('td').eq(3).text().trim(),
               category: $('td').eq(1).text().trim(),
               createdAt: $('td').eq(5).text().trim(),
             };
           }),
           map((meta) => ({
             id: Number.parseInt(meta.link.split('no=')[1].split('&')[0]),
             ...meta,
           })),
         );

85-106: getNoticeDetail에서 파일 링크 생성 시 URL 구성 오류 가능성 확인 필요

파일의 href를 생성할 때 ${this.targetUrl}${$(value).attr('href')}로 구성하고 있습니다. $(value).attr('href')가 절대 경로인 경우 URL이 잘못 형성될 수 있으므로 new URL($(value).attr('href'), this.targetUrl).href를 사용하는 것이 안전합니다.

             href: `${this.targetUrl}${$(value).attr('href')}`,
+            // 또는
+            href: new URL($(value).attr('href'), this.targetUrl).href,
apps/crawler/src/user/user.module.ts (1)

1-2: 상대 경로 대신 절대 경로 사용을 권장

@lib/prisma@nestjs/common 모듈을 임포트할 때 상대 경로 대신 절대 경로 또는 별칭을 사용하면 코드의 가독성과 유지보수성이 향상됩니다.

 import { PrismaModule } from '@lib/prisma';
 import { Module } from '@nestjs/common';

위 코드에서는 이미 절대 경로를 사용하고 있으므로 추가 조치가 필요하지 않습니다. 이 점은 잘 처리된 부분입니다.

apps/crawler/test/crawler.service.spec.ts (3)

32-33: 디버깅용 console.log 문을 제거해주세요.

테스트 코드에 디버깅용 console.log가 남아있습니다. 프로덕션 테스트 코드에서는 제거하는 것이 좋습니다.

-      console.log(noticeList);
-      console.log('noticeList.length:', noticeList.length);

26-35: 테스트 검증을 더 구체적으로 보완해주세요.

현재는 단순히 리스트의 길이만 확인하고 있습니다. 반환된 데이터의 구조와 필수 필드들도 검증하면 좋을 것 같습니다.

       expect(noticeList.length).toBeGreaterThan(0);
+      expect(noticeList[0]).toHaveProperty('title');
+      expect(noticeList[0]).toHaveProperty('link');
+      expect(noticeList[0]).toHaveProperty('date');

46-46: 디버깅용 console.log 문을 제거해주세요.

테스트 코드에 디버깅용 console.log가 남아있습니다.

-      console.log(noticeDetail);
apps/crawler/src/crawler.repository.ts (1)

17-49: 입력값 검증을 추가해주세요.

createCrawl 메소드에 전달되는 매개변수들에 대한 유효성 검사가 없습니다. 특히 필수 필드들에 대한 검증이 필요합니다.

if (!title || !body || !type || !crawledAt || !url || !user) {
  throw new BadRequestException('필수 필드가 누락되었습니다');
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4906bd7 and 81238c5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (46)
  • .github/workflows/production.yml (1 hunks)
  • .github/workflows/staging.yml (2 hunks)
  • .vscode/settings.json (1 hunks)
  • apps/api/src/ai/ai.controller.ts (1 hunks)
  • apps/api/src/ai/ai.module.ts (1 hunks)
  • apps/api/src/api.controller.ts (1 hunks)
  • apps/api/src/api.module.ts (2 hunks)
  • apps/api/src/crawl/crawl.module.ts (1 hunks)
  • apps/api/src/crawl/crawl.service.ts (1 hunks)
  • apps/api/src/document/document.module.ts (1 hunks)
  • apps/api/src/document/document.service.ts (1 hunks)
  • apps/api/src/group/group.controller.ts (1 hunks)
  • apps/api/src/group/group.module.ts (1 hunks)
  • apps/api/src/image/image.module.ts (1 hunks)
  • apps/api/src/image/image.service.ts (1 hunks)
  • apps/api/src/main.ts (1 hunks)
  • apps/api/src/notice/dto/req/additionalNotice.dto.ts (1 hunks)
  • apps/api/src/notice/dto/req/createNotice.dto.ts (1 hunks)
  • apps/api/src/notice/dto/req/foreignContent.dto.ts (1 hunks)
  • apps/api/src/notice/dto/req/getAllNotice.dto.ts (1 hunks)
  • apps/api/src/notice/dto/req/getNotice.dto.ts (1 hunks)
  • apps/api/src/notice/dto/req/reaction.dto.ts (1 hunks)
  • apps/api/src/notice/dto/req/updateNotice.dto.ts (1 hunks)
  • apps/api/src/notice/notice.controller.ts (1 hunks)
  • apps/api/src/notice/notice.module.ts (1 hunks)
  • apps/api/src/notice/notice.repository.ts (4 hunks)
  • apps/api/src/notice/notice.service.ts (1 hunks)
  • apps/api/src/tag/tag.controller.ts (1 hunks)
  • apps/api/src/tag/tag.module.ts (1 hunks)
  • apps/api/src/user/decorator/get-idp-user.decorator.ts (1 hunks)
  • apps/api/src/user/decorator/get-user.decorator.ts (1 hunks)
  • apps/api/src/user/dto/req/login.dto.ts (1 hunks)
  • apps/api/tsconfig.app.json (1 hunks)
  • apps/crawler/Dockerfile (1 hunks)
  • apps/crawler/src/crawler.module.ts (1 hunks)
  • apps/crawler/src/crawler.repository.ts (1 hunks)
  • apps/crawler/src/crawler.service.ts (1 hunks)
  • apps/crawler/src/main.ts (1 hunks)
  • apps/crawler/src/user/user.module.ts (1 hunks)
  • apps/crawler/src/user/user.repository.ts (1 hunks)
  • apps/crawler/src/user/user.service.ts (1 hunks)
  • apps/crawler/test/crawler.service.spec.ts (1 hunks)
  • apps/crawler/test/jest.json (1 hunks)
  • apps/crawler/tsconfig.app.json (1 hunks)
  • nest-cli.json (2 hunks)
  • package.json (4 hunks)
✅ Files skipped from review due to trivial changes (25)
  • apps/api/src/user/decorator/get-idp-user.decorator.ts
  • apps/api/src/notice/dto/req/reaction.dto.ts
  • apps/api/src/user/decorator/get-user.decorator.ts
  • apps/api/src/notice/dto/req/getNotice.dto.ts
  • apps/api/src/api.controller.ts
  • apps/api/src/crawl/crawl.service.ts
  • apps/crawler/tsconfig.app.json
  • apps/api/src/notice/dto/req/createNotice.dto.ts
  • apps/api/src/notice/dto/req/additionalNotice.dto.ts
  • apps/api/src/document/document.service.ts
  • apps/api/src/notice/dto/req/foreignContent.dto.ts
  • apps/api/src/notice/dto/req/updateNotice.dto.ts
  • apps/api/src/image/image.module.ts
  • apps/api/src/group/group.controller.ts
  • apps/api/src/notice/notice.controller.ts
  • apps/api/src/notice/dto/req/getAllNotice.dto.ts
  • apps/api/tsconfig.app.json
  • apps/api/src/document/document.module.ts
  • apps/api/src/notice/notice.service.ts
  • apps/api/src/tag/tag.module.ts
  • apps/api/src/ai/ai.controller.ts
  • apps/api/src/user/dto/req/login.dto.ts
  • apps/crawler/test/jest.json
  • .vscode/settings.json
  • apps/api/src/notice/notice.module.ts
🔇 Additional comments (19)
apps/api/src/image/image.service.ts (2)

9-9: 상대 경로로의 변경이 적절합니다.

절대 경로에서 상대 경로로의 변경은 모듈의 이식성과 유지보수성을 향상시킵니다.


12-14: 로깅 방식의 개선이 확인되었습니다.

Logger 인스턴스를 제거하고 @Loggable() 데코레이터를 사용하는 방식으로 전환한 것이 확인됩니다. 이는 일관된 로깅 처리를 가능하게 합니다.

apps/api/src/tag/tag.controller.ts (1)

24-24: 상대 경로로의 변경이 적절해 보입니다.

프로젝트 구조 개선을 위한 import 경로 표준화가 잘 이루어졌습니다. 다른 컨트롤러들의 변경사항과도 일관성이 있습니다.

아래 스크립트를 실행하여 import 경로가 올바른지 확인하겠습니다:

✅ Verification successful

상대 경로 변경이 정상적으로 이루어졌습니다.

모든 컨트롤러에서 동일한 상대 경로 패턴을 사용하고 있으며, 파일 위치도 정확합니다. 경로 표준화가 성공적으로 완료되었습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the import path exists and is consistent

# Check if the guard file exists at the specified relative path
fd "idp.guard.ts" "apps/api/src/user/guard"

# Verify consistent usage of relative paths for IdPGuard across controllers
rg "import.*IdPGuard.*from.*user/guard/idp.guard" "apps/api/src"

Length of output: 517

apps/api/src/ai/ai.module.ts (1)

6-6: 모듈 임포트 경로 변경이 적절합니다!

상대 경로로의 변경은 모노레포 구조에 더 적합하며, 프로젝트의 모듈성을 향상시킵니다.

apps/api/src/group/group.module.ts (1)

8-8: 일관된 모듈 경로 변경이 확인되었습니다!

다른 모듈들과 동일한 패턴으로 상대 경로가 적용되어 있어 일관성이 잘 유지되었습니다.

apps/api/src/crawl/crawl.module.ts (1)

8-10: 모듈 임포트 경로가 올바르게 변경되었습니다!

여러 모듈의 임포트 경로가 일관되게 상대 경로로 변경되었습니다. 다만, 변경된 경로가 올바르게 동작하는지 확인이 필요합니다.

✅ Verification successful

모듈 임포트 경로가 정상적으로 확인되었습니다!

모든 모듈 파일들이 예상된 위치에서 발견되었으며, 상대 경로를 통한 임포트가 정확히 구성되어 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 변경된 모듈 경로의 유효성 검증
for module in "../user/user.module" "../ai/ai.module" "../fcm/fcm.module"; do
  module_path="apps/api/src/crawl/$module"
  if ! [ -f "$module_path.ts" ]; then
    echo "경고: $module_path.ts 파일을 찾을 수 없습니다."
  fi
done

Length of output: 539


Script:

#!/bin/bash
# Search for module files
echo "Searching for user.module.ts:"
fd "user.module.ts" apps/api/src

echo -e "\nSearching for ai.module.ts:"
fd "ai.module.ts" apps/api/src

echo -e "\nSearching for fcm.module.ts:"
fd "fcm.module.ts" apps/api/src

Length of output: 401

apps/crawler/src/user/user.module.ts (1)

6-11: 모듈 구성 완벽

UserModule의 구성과 프로바이더 설정이 적절하게 이루어져 있습니다. 필요한 서비스와 리포지토리를 제공하고, 외부로 UserService를 내보내어 다른 모듈에서 사용할 수 있게 한 점이 좋습니다.

apps/crawler/src/crawler.module.ts (1)

1-13: 모듈 구조가 잘 설계되었습니다!

NestJS의 모듈 아키텍처 패턴을 잘 따르고 있으며, 필요한 의존성들이 적절하게 주입되어 있습니다.

apps/api/src/api.module.ts (1)

Line range hint 16-56: 모듈 구조 개선이 잘 이루어졌습니다!

AppModule에서 ApiModule로의 이름 변경과 컨트롤러 업데이트가 프로젝트의 모노레포 구조에 잘 부합합니다. 각 기능별 모듈도 깔끔하게 구성되어 있습니다.

apps/api/src/main.ts (1)

7-7: 모듈 변경이 적절히 이루어졌습니다.

모노레포 구조 변경에 따라 AppModule에서 ApiModule로의 전환이 올바르게 이루어졌습니다. 기존 부트스트랩 설정은 그대로 유지되어 있어 안정적입니다.

Also applies to: 10-10

apps/crawler/Dockerfile (1)

2-2: 🛠️ Refactor suggestion

Node.js 버전 및 패키지 설치 방식 검토 필요

  1. node:21-alpine3.18은 매우 최신 버전으로, 프로덕션 환경에서는 안정성이 검증된 LTS 버전(예: node:20-alpine)을 사용하는 것이 좋습니다.
  2. npm install --force 사용은 패키지 충돌을 야기할 수 있으므로 권장되지 않습니다.
-FROM node:21-alpine3.18 AS builder
+FROM node:20-alpine3.18 AS builder

 RUN apk update && \
   apk add build-base libheif vips-dev vips -q
-RUN npm install && npm install --force @img/sharp-linuxmusl-arm64
+RUN npm install

Also applies to: 10-10

✅ Verification successful

Node.js 20 LTS로의 다운그레이드가 안전함을 확인했습니다

  1. 프로젝트의 의존성들이 모두 Node.js 20과 호환됩니다.
  2. Sharp v0.33.2는 Node.js 20에서 정상적으로 동작하며, 아키텍처별 강제 설치가 필요하지 않습니다.

다음과 같이 수정하시기를 권장드립니다:

-FROM node:21-alpine3.18 AS builder
+FROM node:20-alpine3.18 AS builder

 RUN apk update && \
   apk add build-base libheif vips-dev vips -q
-RUN npm install && npm install --force @img/sharp-linuxmusl-arm64
+RUN npm install
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Check package.json for engine requirements and dependencies
echo "=== Checking package.json files ==="
fd package.json --exec cat {}

# Search for potential Node.js 21 specific features
echo -e "\n=== Checking for potential Node.js 21 features ==="
rg -l "node:" .

# Check sharp related configurations
echo -e "\n=== Checking sharp related configurations ==="
rg -l "sharp" .

Length of output: 4332

nest-cli.json (1)

4-4: 모노레포 구성이 적절히 설정되었습니다.

프로젝트 구조가 NestJS 모노레포 베스트 프랙티스를 잘 따르고 있습니다. API와 크롤러 애플리케이션이 독립적으로 구성되어 있어 확장성이 좋습니다.

Also applies to: 8-8, 55-76

.github/workflows/production.yml (1)

52-52: 워크플로우가 새로운 프로젝트 구조에 맞게 수정되었습니다.

Dockerfile 경로가 새로운 모노레포 구조에 맞게 올바르게 지정되었습니다.

.github/workflows/staging.yml (2)

6-6: 워크플로우 트리거 경로가 새로운 프로젝트 구조와 일치하도록 업데이트되었습니다.

apps/api/**로의 경로 변경은 모노레포 구조에 맞게 적절히 수정되었습니다. API 애플리케이션의 변경사항만 워크플로우를 트리거하도록 하여 불필요한 빌드를 방지합니다.


55-55: Dockerfile 경로가 새로운 프로젝트 구조를 반영하도록 업데이트되었습니다.

./apps/api/Dockerfile로의 경로 변경은 모노레포 구조에 맞게 적절히 수정되었습니다.

다음 스크립트를 실행하여 Dockerfile이 올바른 위치에 존재하는지 확인하겠습니다:

✅ Verification successful

Dockerfile 경로 검증이 완료되었습니다

./apps/api/Dockerfile 경로에 파일이 정상적으로 존재함을 확인했습니다. 모노레포 구조에 맞게 올바르게 위치해 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Dockerfile 존재 여부 확인
if [ -f "./apps/api/Dockerfile" ]; then
    echo "Dockerfile exists at the correct location"
else
    echo "ERROR: Dockerfile not found at ./apps/api/Dockerfile"
    exit 1
fi

Length of output: 127

package.json (4)

10-17: 스크립트 경로가 새로운 프로젝트 구조를 반영하도록 업데이트되었습니다.

모노레포 구조로의 전환을 위해 다음과 같이 적절히 수정되었습니다:

  • format 스크립트가 apps와 libs 디렉토리를 대상으로 하도록 변경
  • start 관련 스크립트들이 새로운 디렉토리 구조를 반영
  • 크롤러 서비스를 위한 새로운 스크립트 추가

115-116: Jest 설정이 새로운 프로젝트 구조를 반영하도록 업데이트되었습니다.

테스트 루트 디렉토리가 새로운 모노레포 구조에 맞게 적절히 수정되었습니다.


22-23: 테스트 설정이 새로운 프로젝트 구조를 반영하도록 업데이트되었습니다.

API와 크롤러 서비스에 대한 개별 테스트 설정이 적절히 추가되었습니다.

다음 스크립트를 실행하여 테스트 설정 파일들이 올바른 위치에 존재하는지 확인하겠습니다:

✅ Verification successful

테스트 설정 파일 검증이 완료되었습니다

API와 크롤러 서비스의 테스트 설정 파일이 모두 올바른 위치에 존재함을 확인했습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 테스트 설정 파일 존재 여부 확인
for config in "./apps/api/test/jest-e2e.json" "./apps/crawler/test/jest.json"; do
    if [ -f "$config" ]; then
        echo "Test config exists at: $config"
    else
        echo "ERROR: Test config not found at: $config"
        exit 1
    fi
done

Length of output: 475


39-39: 크롤러 서비스를 위한 새로운 의존성이 추가되었습니다.

cheerio 라이브러리와 해당 타입 정의가 추가되었습니다. 웹 스크래핑을 위한 적절한 선택입니다.

다음 스크립트를 실행하여 크롤러 서비스의 cheerio 사용을 확인하겠습니다:

Also applies to: 61-61

✅ Verification successful

cheerio 라이브러리가 크롤러 서비스에서 적절하게 사용되고 있음을 확인했습니다.

크롤러 서비스에서 cheerio의 load 함수를 정상적으로 임포트하여 사용하고 있습니다. 웹 스크래핑을 위한 의존성이 올바르게 구현되었습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 크롤러 서비스에서 cheerio 사용 확인
rg -l "cheerio" apps/crawler/

Length of output: 65


Script:

#!/bin/bash
# Check cheerio implementation in crawler service
rg "cheerio" apps/crawler/src/crawler.service.ts -B 2 -A 2

Length of output: 198

apps/crawler/src/user/user.service.ts Show resolved Hide resolved
apps/crawler/src/user/user.repository.ts Show resolved Hide resolved
apps/api/src/notice/notice.repository.ts Show resolved Hide resolved
apps/crawler/src/main.ts Show resolved Hide resolved
apps/crawler/src/main.ts Show resolved Hide resolved
apps/crawler/src/crawler.repository.ts Show resolved Hide resolved
apps/crawler/Dockerfile Show resolved Hide resolved
@siwonpada siwonpada merged commit a65b026 into main Jan 19, 2025
2 checks passed
@siwonpada siwonpada deleted the siwonpada/issue143 branch January 21, 2025 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants