Skip to content

Commit

Permalink
Merge pull request #131 from sopt-makers/develop
Browse files Browse the repository at this point in the history
활동후기 삽입 API 추가
  • Loading branch information
Lim-Changi authored Mar 11, 2024
2 parents fa8e061 + f1ecedc commit b4a875d
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 3 deletions.
15 changes: 15 additions & 0 deletions docs/review/review.swagger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { applyDecorators } from '@nestjs/common';
import {
ApiBody,
ApiCreatedResponse,
ApiExtraModels,
ApiOkResponse,
Expand All @@ -9,6 +10,8 @@ import {
} from '@nestjs/swagger';
import { PaginateResponseDto } from '../../src/utils/paginate-response.dto';
import { ReviewsResponseDto } from '../../src/reviews/dtos/reviews-response.dto';
import { CreateSopticleDto } from '../../src/sopticle/dtos/create-sopticle.dto';
import { PutReviewsRequestDto } from '../../src/reviews/dtos/reviews-request.dto';

export function GetReviewsDocs() {
return applyDecorators(
Expand All @@ -34,6 +37,18 @@ export function GetReviewsDocs() {
);
}

export function PutReviewsDocs() {
return applyDecorators(
ApiOperation({
summary: '여러 활동 후기 넣기',
}),
ApiBody({
type: [PutReviewsRequestDto],
}),
ApiCreatedResponse({ type: [ReviewsResponseDto] }),
);
}

export function GetRandomReviewByPart() {
return applyDecorators(
ApiOperation({
Expand Down
15 changes: 14 additions & 1 deletion src/reviews/controllers/reviews.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Body,
Controller,
Get,
Post,
Expand All @@ -11,11 +12,15 @@ import { ReviewsService } from '../services/reviews.service';
import {
GetRandomReviewByPart,
GetReviewsDocs,
PutReviewsDocs,
ReviewEntityMigration,
} from '../../../docs/review/review.swagger';
import { PaginateResponseDto } from '../../utils/paginate-response.dto';
import { ReviewsResponseDto } from '../dtos/reviews-response.dto';
import { ReviewsRequestDto } from '../dtos/reviews-request.dto';
import {
PutReviewsRequestDto,
ReviewsRequestDto,
} from '../dtos/reviews-request.dto';
import { ApiTags } from '@nestjs/swagger';

@UsePipes(new ValidationPipe({ transform: true }))
Expand All @@ -32,6 +37,14 @@ export class ReviewsController {
return await this.reviewsService.getReviews(reviewsRequestDto);
}

@Post()
@PutReviewsDocs()
async putReviews(
@Body() putReviewsDto: [PutReviewsRequestDto],
): Promise<ReviewsResponseDto[]> {
return await this.reviewsService.putReviews(putReviewsDto);
}

@Get('/random')
@GetRandomReviewByPart()
async GetRandomReviewByPart(): Promise<ReviewsResponseDto[]> {
Expand Down
50 changes: 49 additions & 1 deletion src/reviews/dtos/reviews-request.dto.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { PageRequest } from '../../utils/paginate-request.dto';
import { ApiProperty } from '@nestjs/swagger';
import { Part } from '../../common/type';
import { IsNumber, IsOptional } from 'class-validator';
import { IsArray, IsNumber, IsOptional } from 'class-validator';
import { Transform } from 'class-transformer';
import { string } from 'joi';

export class ReviewsRequestDto extends PageRequest {
@ApiProperty({
Expand All @@ -24,3 +25,50 @@ export class ReviewsRequestDto extends PageRequest {
@IsOptional()
readonly generation: number | null;
}

export class PutReviewsRequestDto {
@ApiProperty({
required: true,
description: '활동후기 링크',
type: String,
})
readonly url: string;

@ApiProperty({
type: String,
enum: Part,
required: true,
})
readonly part: Part;

@ApiProperty({
required: true,
description:
'활동기수로 필터링 합니다, 값을 넣지 않을 경우 전체 조회합니다.',
type: Number,
})
@Transform(({ value }) => parseInt(value))
@IsNumber()
readonly generation: number;

@ApiProperty({
required: true,
description: '작성자',
type: String,
})
readonly author: string;

@ApiProperty({
required: true,
description: '활동 종류',
type: String,
})
readonly subject: string;

@ApiProperty({
required: true,
description: '활동후기 플랫폼',
type: String,
})
readonly platform: string;
}
36 changes: 36 additions & 0 deletions src/reviews/entities/reviews.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
import { Part } from '../../common/type';
import { Sopticle } from '../../sopticle/entities/sopticle.entity';

@Index('review_pk', ['id'], { unique: true })
@Entity('Review', { schema: 'public' })
Expand Down Expand Up @@ -36,4 +37,39 @@ export class Review {

@Column('varchar', { name: 'url', nullable: false, length: 500 })
url: string;

static from(params: {
title: string;
author: string;
part: Part;
generation: number;
subject: string;
thumbnailUrl: string;
platform: string;
url: string;
description: string;
}) {
const review = new Review();
const {
title,
author,
generation,
part,
subject,
thumbnailUrl,
platform,
url,
description,
} = params;
review.title = title;
review.author = author;
review.generation = generation;
review.part = part;
review.subject = subject;
review.thumbnailUrl = thumbnailUrl;
review.platform = platform;
review.url = url;
review.description = description;
return review;
}
}
44 changes: 43 additions & 1 deletion src/reviews/services/reviews.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Review } from 'src/reviews/entities/reviews.entity';
import { Repository } from 'typeorm';
import { ReviewsResponseDto } from '../dtos/reviews-response.dto';
import { ReviewsRequestDto } from '../dtos/reviews-request.dto';
import {
PutReviewsRequestDto,
ReviewsRequestDto,
} from '../dtos/reviews-request.dto';
import { PaginateResponseDto } from '../../utils/paginate-response.dto';
import { Part } from '../../common/type';
import { ScraperService } from '../../scraper/scraper.service';
Expand Down Expand Up @@ -54,6 +57,45 @@ export class ReviewsService {
);
}

async putReviews(dto: PutReviewsRequestDto[]): Promise<Review[]> {
const promiseList: any[] = [];
const result: Review[] = [];
const allReviews = await this.reviewsRepository.find();
const allReviewUrls = allReviews.map((data) => {
return data.url;
});

for (const review of dto) {
if (allReviewUrls.includes(review.url)) continue;
promiseList.push(async () => {
const scrapResult = await this.scrapperService.scrap({
articleUrl: review.url,
});

const reviewEntity = await this.reviewsRepository.save(
Review.from({
title: scrapResult.title,
description: scrapResult.description,
thumbnailUrl: scrapResult.thumbnailUrl,
generation: review.generation,
url: review.url,
part: review.part,
platform: review.platform,
author: review.author,
subject: review.subject,
}),
);
result.push(reviewEntity);
});
}
await Promise.all(
promiseList.map((promise) => {
return promise();
}),
);
return result;
}

async getRandomReviewByPart(): Promise<Review[]> {
const parts: Part[] = Object.values(Part);
return (await Promise.all(
Expand Down

0 comments on commit b4a875d

Please sign in to comment.