From e4c9e98d7d78142eb0271041ad9a335ef7beb7a4 Mon Sep 17 00:00:00 2001 From: Kimcheolhui Date: Mon, 9 Dec 2024 14:07:51 +0900 Subject: [PATCH 1/3] chore: add checking logic when get all comments by post id --- src/comment/comment.service.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/comment/comment.service.ts b/src/comment/comment.service.ts index dd6550d..27e095b 100644 --- a/src/comment/comment.service.ts +++ b/src/comment/comment.service.ts @@ -50,6 +50,12 @@ export class CommentService { } async getPostComments(postId: number): Promise { + const post = this.postService.getPostById(postId); + + if (!post) { + throw new NotFoundException('Post not found'); + } + return this.commentRepository.getPostComments(postId); } From bb8f73d53097320bc68cb23b0769ee7f72b3c8ed Mon Sep 17 00:00:00 2001 From: Kimcheolhui Date: Mon, 9 Dec 2024 18:29:48 +0900 Subject: [PATCH 2/3] chore: install form-data package for ai feature --- package-lock.json | 2 ++ package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/package-lock.json b/package-lock.json index 8fc9803..2c42507 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "class-validator": "^0.14.1", "cookie-parser": "^1.4.7", "express-basic-auth": "^1.2.1", + "form-data": "^4.0.1", "passport": "^0.7.0", "passport-http-bearer": "^1.0.1", "passport-oauth2": "^1.8.0", @@ -6741,6 +6742,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", diff --git a/package.json b/package.json index 2da6896..27fad56 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "class-validator": "^0.14.1", "cookie-parser": "^1.4.7", "express-basic-auth": "^1.2.1", + "form-data": "^4.0.1", "passport": "^0.7.0", "passport-http-bearer": "^1.0.1", "passport-oauth2": "^1.8.0", From bbddd43354848c485b505246613ba9a4370a6800 Mon Sep 17 00:00:00 2001 From: Kimcheolhui Date: Mon, 9 Dec 2024 18:30:46 +0900 Subject: [PATCH 3/3] feat: apply image masking feature --- src/image/image.service.ts | 47 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/image/image.service.ts b/src/image/image.service.ts index 51a0a88..6a27569 100644 --- a/src/image/image.service.ts +++ b/src/image/image.service.ts @@ -13,7 +13,8 @@ import { NotFoundException, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; - +import axios from 'axios'; +import FormData from 'form-data'; import sharp from 'sharp'; @Injectable() @@ -53,7 +54,13 @@ export class ImageService { private async uploadImage(file: Express.Multer.File): Promise { const key = `${Date.now()}-${Math.random().toString(36).substring(2)}${file.originalname}`; - const webpFile = await this.convertToWebp(file); + // OCR Masking + const maskedImageBuffer = await this.maskingImageWithFlask(file); + + const webpFile = await this.convertToWebp({ + ...file, + buffer: maskedImageBuffer, + }); const command = new PutObjectCommand({ Bucket: this.bucketName, @@ -172,4 +179,40 @@ export class ImageService { throw new InternalServerErrorException('Failed to generate signed URLs'); } } + + /** + * AI feature 서버에 이미지를 보내서 OCR 마스킹 처리 + * @param file Express.Multer.File + * @returns Buffer (마스킹된 이미지 데이터) + */ + private async maskingImageWithFlask( + file: Express.Multer.File, + ): Promise { + const flaskApiUrl = this.configService.get('FLASK_API_URL'); // Flask API URL + const flaskApiKey = this.configService.get('FLASK_API_KEY'); // Flask API Key + + try { + const formData = new FormData(); + formData.append('image', file.buffer, file.originalname); + + const response = await axios.post( + `${flaskApiUrl}/process_image`, + formData, + { + headers: { + 'X-API-KEY': flaskApiKey, + ...formData.getHeaders(), + }, + responseType: 'arraybuffer', // 이미지 데이터를 Buffer로 받기 + }, + ); + + return Buffer.from(response.data); // 마스킹된 이미지 데이터 반환 + } catch (error) { + console.error('Error calling Flask API:', error.message); + throw new InternalServerErrorException( + 'Failed to process image with Flask API', + ); + } + } }