Skip to content

Commit

Permalink
feat: 서비스 페이지 측 API 구현
Browse files Browse the repository at this point in the history
- search 관련 기능 구현. 키워드 목록, 키워드 + 기사 문장 등 기능 구현함
  • Loading branch information
blaxsior committed Nov 1, 2023
1 parent 5217701 commit 2ec5bcf
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 19 deletions.
2 changes: 1 addition & 1 deletion backend/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '3'
services:
backend:
ports:
- 8080:8080
- 3030:8080
depends_on:
- my-redis # redis 동작해야 의미 O
build:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Test, TestingModule } from '@nestjs/testing';
import { AnalysisCommentController } from './analysis-comment.controller';
import { AnalysisCommentService } from './analysis-comment.service';
import { CreateCommentDto } from './dtos/create-comment.dto';
import { GetCommentsQueriesDto } from './dtos/get-comments-query.dto';
import { AuthGuard } from '../auth/auth.guard';

jest.mock('./analysis-comment.service');
Expand Down Expand Up @@ -51,13 +50,11 @@ describe('AnalysisCommentController', () => {
describe('getComments()', () => {
it('call commentService.getComments', async () => {
// dummy data
const dummyDto: GetCommentsQueriesDto = {
search: '',
};
const comment_id = 1;
// action
await controller.getComments(dummyDto);
await controller.getComment(comment_id);
// assert
expect(service.findMany).toBeCalled();
expect(service.findManyWithQuery).toBeCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Controller, Post, Get, Body, Query, UseGuards } from '@nestjs/common';
import { Controller, Post, Get, Body, UseGuards, Param } from '@nestjs/common';
import { ApiBearerAuth, ApiResponse, ApiTags } from '@nestjs/swagger';

import { CreateCommentDto } from './dtos/create-comment.dto';
import { GetCommentsQueriesDto } from './dtos/get-comments-query.dto';
import { AnalysisCommentService } from './analysis-comment.service';
import { AuthGuard } from '../auth/auth.guard';

Expand Down Expand Up @@ -33,9 +32,9 @@ export class AnalysisCommentController {
description: '가져온 댓글 목록',
status: 200,
})
@Get()
async getComments(@Query() queries: GetCommentsQueriesDto) {
const comments = await this.commentService.findMany(queries);
return comments;
@Get(':id')
async getComment(@Param('id') id: number) {
const comment = await this.commentService.findOneById(id);
return comment;
}
}
56 changes: 54 additions & 2 deletions backend/server/src/analysis-comment/analysis-comment.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { Between, DataSource, FindOperator, Repository } from 'typeorm';
import { AnalysisComment } from './entity/analysis-comment.entity';
import { CreateCommentDto } from './dtos/create-comment.dto';
import { ArticleContent } from './entity/article-content.entity';
import { GetCommentsQueriesDto } from './dtos/get-comments-query.dto';

@Injectable()
export class AnalysisCommentService {
constructor(
Expand Down Expand Up @@ -40,7 +41,58 @@ export class AnalysisCommentService {
return comment;
}

async findMany({ search, psize, head_id, from, to }: GetCommentsQueriesDto) {
/**
* id 기반으로 댓글을 검색한다. 연관 기사 문장과 함께 가져올지 지정할 수 있다.
*/
async findOneById(id: number, isWithSentences = true) {
return await this.comment_repo.findOne({
where: {
id: id,
},
relations: {
news_sentences: isWithSentences,
},
});
}

/**
* commment 정보를 이용하여 연관된 키워드 목록을 가져온다
*/
async findManyByInfo(info: {
keyword_id: number;
emotion: string;
count: number;
from?: string;
to?: string;
}) {
const { keyword_id, emotion, count, from, to } = info;
let between: FindOperator<Date> | undefined;
if (from && to) {
between = Between(new Date(from), new Date(to));
}

await this.comment_repo.find({
where: {
keyword_id: keyword_id,
emotion: emotion,
createdAt: between,
},
order: {
sympathy: {
direction: 'DESC',
},
},
take: count,
});
}

async findManyWithQuery({
search,
psize,
head_id,
from,
to,
}: GetCommentsQueriesDto) {
if (!search) return [];

const qb = this.comment_repo.createQueryBuilder();
Expand Down
18 changes: 18 additions & 0 deletions backend/server/src/app.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';

describe('AppController', () => {
let controller: AppController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AppController],
}).compile();

controller = module.get<AppController>(AppController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
23 changes: 23 additions & 0 deletions backend/server/src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Controller, Get } from '@nestjs/common';

@Controller()
export class AppController {
/**
* 접근 가능한 메인 주소
*/
@Get()
sayHello() {
return `
<!DOCTYPE html>
<html>
<head>
<title>keyword-on</title>
<meta charset='utf8'>
</head>
<body>
<h1>Keyword-on에 어서 오세요</h1>
<p>키워드 온 메인 페이지입니다!</p>
</body>
</html>`;
}
}
2 changes: 2 additions & 0 deletions backend/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TokenModule } from './token/token.module';
import { RedisModule } from './redis/redis.module';
import { SearchModule } from './search/search.module';
import { BatchModule } from './batch/batch.module';
import { AppController } from './app.controller';

@Module({
imports: [
Expand All @@ -28,5 +29,6 @@ import { BatchModule } from './batch/batch.module';
SearchModule,
BatchModule,
],
controllers: [AppController],
})
export class AppModule {}
17 changes: 14 additions & 3 deletions backend/server/src/search/search.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Controller, Get, Query } from '@nestjs/common';
import { Controller, Get, Query, Param } from '@nestjs/common';
import { ApiResponse, ApiTags } from '@nestjs/swagger';

import { SearchService } from './search.service';
Expand Down Expand Up @@ -30,7 +30,7 @@ export class SearchController {
async getPopularKeywords(
@Query() dto: PopularKeywordsReqQueryDto,
): Promise<PopularKeywordsResDto[]> {
const keywords = await this.service.findManyPopularKeywords(dto.count!);
const keywords = await this.service.getManyPopularKeywords(dto.count!);
const results = keywords.map((keyword) => {
const { id, description, name } = keyword;
return { id, description, name };
Expand All @@ -47,7 +47,7 @@ export class SearchController {
type: () => KeywordWithTopCommentsResDto,
})
@Serialize(KeywordWithTopCommentsResDto)
@Get('keyword')
@Get('keyword-search-result')
async getKeywordWithTopComments(
@Query() dto: KeywordWithTopCommentsReqQueryDto,
) {
Expand All @@ -58,4 +58,15 @@ export class SearchController {
to,
);
}

/**
* 선택한 댓글의 정보를 연관 문장과 함께 가져온다
*/
@ApiResponse({
status: 200,
})
@Get('detail/comment/:id')
async getCommentWithSentences(@Param('id') id: number) {
return await this.service.getCommentWithSentences(id);
}
}
25 changes: 24 additions & 1 deletion backend/server/src/search/search.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class SearchService {
/**
* 인기 있는 키워드 목록을 반환한다. 메인 화면에서 사용됨.
*/
async findManyPopularKeywords(count: number): Promise<Keyword[]> {
async getManyPopularKeywords(count: number): Promise<Keyword[]> {
const key = this.config.get('POPULAR_KEYWORDS_KEY');
const keyword_ids = (await this.redisStore.zrevrange(key, 0, count)).map(
(it) => parseInt(it),
Expand Down Expand Up @@ -64,4 +64,27 @@ export class SearchService {
const key = this.config.get('POPULAR_KEYWORDS_KEY');
return await this.redisStore.del(key);
}

/**
* 댓글을 관련된 문장과 함께 가져오기
*/
async getCommentWithSentences(id: number) {
const commentWithSentences = await this.commentService.findOneById(
id,
true,
);
if (!commentWithSentences)
throw new NotFoundException(`there is no comment id: ${id}`);
return commentWithSentences;
}

async getRelatedKeywordList(info: {
keyword_id: number;
emotion: string;
count: number;
from?: string;
to?: string;
}) {
return await this.commentService.findManyByInfo(info);
}
}

0 comments on commit 2ec5bcf

Please sign in to comment.