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

refactor: 전체적인 코드 리뷰 #69

Merged
merged 8 commits into from
Sep 13, 2024
20 changes: 7 additions & 13 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@ import tseslint from 'typescript-eslint';
import prettierConfig from 'eslint-config-prettier';
import prettierRecommended from 'eslint-plugin-prettier/recommended';

export default tseslint.config(
{
files: ['**/*.js', '**/*.mjs', '**/*.ts'],
extends: [eslint.configs.recommended, ...tseslint.configs.recommended],
rules: {
'no-console': 'warn',
},
export default tseslint.config({
files: ['**/*.js', '**/*.mjs', '**/*.ts'],
extends: [eslint.configs.recommended, ...tseslint.configs.recommended, prettierRecommended],
rules: {
...prettierConfig.rules,
'no-console': 'warn',
},
{
files: ['**/*.js', '**/*.mjs', '**/*.ts'],
extends: [prettierRecommended],
rules: prettierConfig.rules,
},
);
});
18 changes: 9 additions & 9 deletions src/domain/activity/study/controller/study.admin.controller.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Body, Controller, Delete, Patch, Put } from '@nestjs/common';
import { ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';

import { AuthAdminAccount, AuthAdminAccountException, ReqMember } from '@wink/auth/guard';

import { Member } from '@wink/member/schema';
import { AuthAdminAccount, AuthAdminAccountException } from '@wink/auth/guard';

import {
CreateCategoryRequestDto,
Expand All @@ -16,6 +14,7 @@ import {
} from '@wink/activity/dto';
import {
AlreadyExistsCategoryException,
AlreadyExistsStudyException,
CategoryNotFoundException,
StudyNotFoundException,
} from '@wink/activity/exception';
Expand Down Expand Up @@ -65,12 +64,13 @@ export class StudyAdminController {
@ApiOperation({ summary: '스터디 생성' })
@ApiProperty({ type: CreateStudyRequestDto })
@ApiCustomResponse(CreateStudyResponseDto)
@ApiCustomErrorResponse([...AuthAdminAccountException, CategoryNotFoundException])
async createStudy(
@ReqMember() member: Member,
@Body() request: CreateStudyRequestDto,
): Promise<CreateStudyResponseDto> {
return this.studyAdminService.createStudy(member, request);
@ApiCustomErrorResponse([
...AuthAdminAccountException,
CategoryNotFoundException,
AlreadyExistsStudyException,
])
async createStudy(@Body() request: CreateStudyRequestDto): Promise<CreateStudyResponseDto> {
return this.studyAdminService.createStudy(request);
}

@Delete()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { HttpStatus } from '@nestjs/common';

import { ApiException } from '@wink/swagger';

export class AlreadyExistsStudyException extends ApiException {
constructor() {
super({
swagger: '스터디가 이미 존재하는 경우',
message: '스터디가 이미 존재합니다.',
code: HttpStatus.CONFLICT,
});
}
}
2 changes: 1 addition & 1 deletion src/domain/activity/study/exception/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './already-exists-category.exception';
export * from './already-exists-study.exception';
export * from './category-not-found.exception';

export * from './study-not-found.exception';
4 changes: 0 additions & 4 deletions src/domain/activity/study/repository/category.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ export class CategoryRepository {
return this.categoryModel.find().exec();
}

async findById(id: string): Promise<Category | null> {
return this.categoryModel.findById(id).exec();
}

async findByName(name: string): Promise<Category | null> {
return this.categoryModel.findOne({ name }).exec();
}
Expand Down
8 changes: 4 additions & 4 deletions src/domain/activity/study/repository/study.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ export class StudyRepository {
.exec();
}

async findById(id: string): Promise<Study | null> {
return this.studyModel.findById(id).exec();
}

// Delete
async deleteById(id: string): Promise<void> {
await this.studyModel.deleteOne({ _id: id }).exec();
Expand All @@ -41,4 +37,8 @@ export class StudyRepository {
async existsById(id: string): Promise<boolean> {
return !!(await this.studyModel.exists({ _id: id }).exec());
}

async existsByLink(link: string): Promise<boolean> {
return !!(await this.studyModel.exists({ link }).exec());
}
}
21 changes: 11 additions & 10 deletions src/domain/activity/study/service/study.admin.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Injectable } from '@nestjs/common';

import { Member } from '@wink/member/schema';

import {
CreateCategoryRequestDto,
CreateCategoryResponseDto,
Expand All @@ -13,6 +11,7 @@ import {
} from '@wink/activity/dto';
import {
AlreadyExistsCategoryException,
AlreadyExistsStudyException,
CategoryNotFoundException,
StudyNotFoundException,
} from '@wink/activity/exception';
Expand Down Expand Up @@ -59,34 +58,36 @@ export class StudyAdminService {
await this.categoryRepository.deleteById(categoryId);
}

async createStudy(
member: Member,
{ link }: CreateStudyRequestDto,
): Promise<CreateStudyResponseDto> {
async createStudy({ link }: CreateStudyRequestDto): Promise<CreateStudyResponseDto> {
if (await this.studyRepository.existsByLink(link)) {
throw new AlreadyExistsStudyException();
}

const { data: html } = await axios.get(link);
const $ = cheerio.load(html);

const title = $('meta[property="og:title"]').attr('content')!;
const content = $('meta[property="og:description"]').attr('content')!;
const author = $('meta[property="og.article.author"]').attr('content')!;
const image = $('meta[property="og:image"]').attr('content')!;
const uploadedAt = $('meta[property="article:published_time"]').attr('content')!;
const rawUploadedAt = $('meta[property="article:published_time"]').attr('content')!;
const uploadedAt = new Date(new Date(rawUploadedAt).getTime() + 9 * 60 * 60 * 1000);

const entryInfoMatch = html.match(/window\.T\.entryInfo\s*=\s*({[^}]*});/);
const entryInfo = entryInfoMatch ? JSON.parse(entryInfoMatch[1]) : null;
const categoryLabel = entryInfo['categoryLabel'];

const category = await this.categoryRepository.findByName(categoryLabel);

if (!category) {
throw new CategoryNotFoundException();
}

const study: Partial<Study> = {
author: member,
title,
content,
author,
image,
uploadedAt: new Date(uploadedAt),
uploadedAt,
link,
category,
};
Expand Down
34 changes: 0 additions & 34 deletions src/domain/member/constant/Role.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/domain/member/constant/index.ts

This file was deleted.

12 changes: 6 additions & 6 deletions src/domain/member/repository/member.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ export class MemberRepository {
}

// Update
async updatePassword(id: string, password: string): Promise<void> {
async updatePasswordById(id: string, password: string): Promise<void> {
await this.memberModel.updateOne({ _id: id }, { password }).exec();
}

async updateDescription(id: string, description: string | null): Promise<void> {
async updateDescriptionById(id: string, description: string | null): Promise<void> {
await this.memberModel.updateOne({ _id: id }, { description }).exec();
}

async updateGithub(id: string, githubUrl: string | null): Promise<void> {
async updateGithubUrlById(id: string, githubUrl: string | null): Promise<void> {
await this.memberModel.updateOne({ _id: id }, { 'link.github': githubUrl }).exec();
}

async updateInstagram(id: string, instagramUrl: string | null): Promise<void> {
async updateInstagramUrlById(id: string, instagramUrl: string | null): Promise<void> {
await this.memberModel.updateOne({ _id: id }, { 'link.instagram': instagramUrl }).exec();
}

async updateBlog(id: string, blog: string | null): Promise<void> {
async updateBlogById(id: string, blog: string | null): Promise<void> {
await this.memberModel.updateOne({ _id: id }, { 'link.blog': blog }).exec();
}

async updateAvatar(id: string, avatar: string | null): Promise<void> {
async updateAvatarById(id: string, avatar: string | null): Promise<void> {
await this.memberModel.updateOne({ _id: id }, { avatar }).exec();
}

Expand Down
14 changes: 7 additions & 7 deletions src/domain/member/service/member.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ export class MemberService {
): Promise<void> {
const { _id: id } = member;

await this.memberRepository.updateDescription(id, description);
await this.memberRepository.updateGithub(id, github);
await this.memberRepository.updateInstagram(id, instagram);
await this.memberRepository.updateBlog(id, blog);
await this.memberRepository.updateDescriptionById(id, description);
await this.memberRepository.updateGithubUrlById(id, github);
await this.memberRepository.updateInstagramUrlById(id, instagram);
await this.memberRepository.updateBlogById(id, blog);

this.eventEmitter.emit(
UpdateMyInfoEvent.EVENT_NAME,
Expand All @@ -73,7 +73,7 @@ export class MemberService {
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(newPassword, salt);

await this.memberRepository.updatePassword(id, hash);
await this.memberRepository.updatePasswordById(id, hash);

this.eventEmitter.emit(UpdateMyPasswordEvent.EVENT_NAME, new UpdateMyPasswordEvent(member));
}
Expand All @@ -85,7 +85,7 @@ export class MemberService {
const { _id: id, avatar: original } = member;

const avatar = await this.avatarService.upload(file);
await this.memberRepository.updateAvatar(id, avatar);
await this.memberRepository.updateAvatarById(id, avatar);

if (original) {
const key = this.avatarService.extractKeyFromUrl(original);
Expand All @@ -105,7 +105,7 @@ export class MemberService {
const key = this.avatarService.extractKeyFromUrl(avatar);

await this.avatarService.delete(key);
await this.memberRepository.updateAvatar(id, null);
await this.memberRepository.updateAvatarById(id, null);

this.eventEmitter.emit(DeleteMyAvatarEvent.EVENT_NAME, new DeleteMyAvatarEvent(member));
}
Expand Down
1 change: 0 additions & 1 deletion test/mock/module/auth.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { AuthService } from '@wink/auth/service';
import { MemberRepository } from '@wink/member/repository';
import { Member } from '@wink/member/schema';

import { RedisService } from '@wink/redis';
import { MailService } from '@wink/mail';
import { ConfigService } from '@nestjs/config';

Expand Down
Loading