Skip to content

Commit

Permalink
Merge pull request #14 from boostcampwm-2024/refactor/repository-reus…
Browse files Browse the repository at this point in the history
…e-admin

♻️ refactor: admin 도메인 repository 함수 재사용성 향상, 테스트 코드 일관성, 최적화
  • Loading branch information
Jo-Minseok authored Jan 14, 2025
2 parents 824225d + 16a182b commit 30c258c
Show file tree
Hide file tree
Showing 19 changed files with 193 additions and 153 deletions.
11 changes: 11 additions & 0 deletions server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/bcrypt": "^5.0.2",
"@types/cookie-parser": "^1.4.7",
"@types/eventsource": "^1.1.15",
"@types/express": "^5.0.0",
Expand Down
8 changes: 4 additions & 4 deletions server/src/admin/controller/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export class AdminController {
@Post('/login')
@HttpCode(HttpStatus.OK)
async loginAdmin(
@Body() loginAdminDto: LoginAdminRequestDto,
@Body() loginAdminBodyDto: LoginAdminRequestDto,
@Res({ passthrough: true }) response: Response,
@Req() request: Request,
) {
await this.adminService.loginAdmin(loginAdminDto, response, request);
await this.adminService.loginAdmin(loginAdminBodyDto, response, request);
return ApiResponse.responseWithNoContent(
'로그인이 성공적으로 처리되었습니다.',
);
Expand All @@ -57,8 +57,8 @@ export class AdminController {
@ApiCreateAdmin()
@UseGuards(CookieAuthGuard)
@Post('/register')
async createAdmin(@Body() registerAdminDto: RegisterAdminRequestDto) {
await this.adminService.createAdmin(registerAdminDto);
async createAdmin(@Body() registerAdminBodyDto: RegisterAdminRequestDto) {
await this.adminService.createAdmin(registerAdminBodyDto);
return ApiResponse.responseWithNoContent(
'성공적으로 관리자 계정이 생성되었습니다.',
);
Expand Down
4 changes: 4 additions & 0 deletions server/src/admin/dto/request/login-admin.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ export class LoginAdminRequestDto {
message: '문자열을 입력해주세요',
})
password: string;

constructor(partial: Partial<LoginAdminRequestDto>) {
Object.assign(this, partial);
}
}
11 changes: 11 additions & 0 deletions server/src/admin/dto/request/register-admin.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IsString, Length, Matches } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Admin } from '../../entity/admin.entity';

const PASSWORD_REG = /^(?=.*[!@#$%^&*()_+])[A-Za-z0-9!@#$%^&*()_+]+$/;

Expand Down Expand Up @@ -32,4 +33,14 @@ export class RegisterAdminRequestDto {
message: '패스워드의 길이는 6자 이상, 60자 이하로 작성해주세요.',
})
password: string;

constructor(partial: Partial<RegisterAdminRequestDto>) {
Object.assign(this, partial);
}

toEntity() {
const admin = new Admin();
Object.assign(admin, this);
return admin;
}
}
11 changes: 0 additions & 11 deletions server/src/admin/repository/admin.repository.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { Admin } from '../entity/admin.entity';
import { RegisterAdminRequestDto } from '../dto/request/register-admin.dto';

@Injectable()
export class AdminRepository extends Repository<Admin> {
constructor(private dataSource: DataSource) {
super(Admin, dataSource.createEntityManager());
}

async createAdmin(registerAdminDto: RegisterAdminRequestDto) {
const { loginId, password } = registerAdminDto;
const admin = this.create({
loginId,
password,
});
await this.save(admin);
return admin;
}
}
17 changes: 9 additions & 8 deletions server/src/admin/service/admin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ export class AdminService {
) {}

async loginAdmin(
loginAdminDto: LoginAdminRequestDto,
loginAdminBodyDto: LoginAdminRequestDto,
response: Response,
request: Request,
) {
const cookie = request.cookies['sessionId'];
const { loginId, password } = loginAdminDto;
const { loginId, password } = loginAdminBodyDto;

const admin = await this.adminRepository.findOne({
where: { loginId },
Expand Down Expand Up @@ -90,20 +90,21 @@ export class AdminService {
response.clearCookie('sessionId');
}

async createAdmin(registerAdminDto: RegisterAdminRequestDto) {
let { loginId, password } = registerAdminDto;

async createAdmin(registerAdminBodyDto: RegisterAdminRequestDto) {
const existingAdmin = await this.adminRepository.findOne({
where: { loginId },
where: { loginId: registerAdminBodyDto.loginId },
});

if (existingAdmin) {
throw new ConflictException('이미 존재하는 아이디입니다.');
}

const saltRounds = 10;
password = await bcrypt.hash(password, saltRounds);
registerAdminBodyDto.password = await bcrypt.hash(
registerAdminBodyDto.password,
saltRounds,
);

await this.adminRepository.createAdmin({ loginId, password });
await this.adminRepository.save(registerAdminBodyDto.toEntity());
}
}
14 changes: 8 additions & 6 deletions server/src/feed/controller/feed.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ export class FeedController {
@ApiReadFeedPagination()
@Get('')
@HttpCode(HttpStatus.OK)
async readFeedPagination(@Query() queryFeedDto: FeedPaginationRequestDto) {
async readFeedPagination(
@Query() feedPaginationQueryDto: FeedPaginationRequestDto,
) {
return ApiResponse.responseWithData(
'피드 조회 완료',
await this.feedService.readFeedPagination(queryFeedDto),
await this.feedService.readFeedPagination(feedPaginationQueryDto),
);
}

Expand Down Expand Up @@ -75,23 +77,23 @@ export class FeedController {
@ApiSearchFeedList()
@Get('search')
@HttpCode(HttpStatus.OK)
async searchFeedList(@Query() searchFeedReq: SearchFeedRequestDto) {
async searchFeedList(@Query() searchFeedQueryDto: SearchFeedRequestDto) {
return ApiResponse.responseWithData(
'검색 결과 조회 완료',
await this.feedService.searchFeedList(searchFeedReq),
await this.feedService.searchFeedList(searchFeedQueryDto),
);
}

@ApiUpdateFeedViewCount()
@Post('/:feedId')
@HttpCode(HttpStatus.OK)
async updateFeedViewCount(
@Param() params: FeedViewUpdateRequestDto,
@Param() viewUpdateParamDto: FeedViewUpdateRequestDto,
@Req() request: Request,
@Res({ passthrough: true }) response: Response,
) {
await this.feedService.updateFeedViewCount(
params.feedId,
viewUpdateParamDto,
request,
response,
);
Expand Down
23 changes: 13 additions & 10 deletions server/src/feed/service/feed.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
FeedTrendResponseDto,
} from '../dto/response/feed-pagination.dto';
import { RedisService } from '../../common/redis/redis.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { SearchFeedRequestDto } from '../dto/request/search-feed.dto';
import { Response, Request } from 'express';
import { cookieConfig } from '../../common/cookie/cookie.config';
Expand All @@ -29,20 +28,21 @@ import {
FeedRecentRedis,
FeedRecentResponseDto,
} from '../dto/response/recent.dto';
import { FeedViewUpdateRequestDto } from '../dto/request/feed-update.dto';

@Injectable()
export class FeedService {
constructor(
private readonly feedRepository: FeedRepository,
private readonly feedViewRepository: FeedViewRepository,
private readonly redisService: RedisService,
private readonly eventService: EventEmitter2,
) {}

async readFeedPagination(queryFeedDto: FeedPaginationRequestDto) {
const feedList =
await this.feedViewRepository.findFeedPagination(queryFeedDto);
const hasMore = this.existNextFeed(feedList, queryFeedDto.limit);
async readFeedPagination(feedPaginationQueryDto: FeedPaginationRequestDto) {
const feedList = await this.feedViewRepository.findFeedPagination(
feedPaginationQueryDto,
);
const hasMore = this.existNextFeed(feedList, feedPaginationQueryDto.limit);
if (hasMore) feedList.pop();
const lastId = this.getLastIdFromFeedList(feedList);
const newCheckFeedList = await this.checkNewFeeds(feedList);
Expand Down Expand Up @@ -94,8 +94,8 @@ export class FeedService {
);
}

async searchFeedList(searchFeedReq: SearchFeedRequestDto) {
const { find, page, limit, type } = searchFeedReq;
async searchFeedList(searchFeedQueryDto: SearchFeedRequestDto) {
const { find, page, limit, type } = searchFeedQueryDto;
const offset = (page - 1) * limit;

if (!this.validateSearchType(type)) {
Expand Down Expand Up @@ -131,15 +131,18 @@ export class FeedService {
}

async updateFeedViewCount(
feedId: number,
viewUpdateParamDto: FeedViewUpdateRequestDto,
request: Request,
response: Response,
) {
const cookie = request.headers.cookie;
const ip = this.getIp(request);
const feedId = viewUpdateParamDto.feedId;
if (ip && this.isString(ip)) {
const [feed, hasCookie, hasIpFlag] = await Promise.all([
this.feedRepository.findOne({ where: { id: feedId } }),
this.feedRepository.findOne({
where: { id: feedId },
}),
Boolean(cookie?.includes(`View_count_${feedId}=${feedId}`)),
this.redisService.sismember(`feed:${feedId}:ip`, ip),
]);
Expand Down
14 changes: 7 additions & 7 deletions server/src/rss/controller/rss.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export class RssController {

@ApiCreateRss()
@Post()
async createRss(@Body() rssRegisterDto: RssRegisterRequestDto) {
await this.rssService.createRss(rssRegisterDto);
async createRss(@Body() rssRegisterBodyDto: RssRegisterRequestDto) {
await this.rssService.createRss(rssRegisterBodyDto);
return ApiResponse.responseWithNoContent('신청이 완료되었습니다.');
}

Expand All @@ -47,8 +47,8 @@ export class RssController {
@UseGuards(CookieAuthGuard)
@Post('accept/:id')
@HttpCode(201)
async acceptRss(@Param() params: RssManagementRequestDto) {
await this.rssService.acceptRss(params.id);
async acceptRss(@Param() rssAcceptParamDto: RssManagementRequestDto) {
await this.rssService.acceptRss(rssAcceptParamDto);
return ApiResponse.responseWithNoContent('승인이 완료되었습니다.');
}

Expand All @@ -57,10 +57,10 @@ export class RssController {
@Post('reject/:id')
@HttpCode(201)
async rejectRss(
@Body() body: RejectRssRequestDto,
@Param() params: RssManagementRequestDto,
@Body() rssRejectBodyDto: RejectRssRequestDto,
@Param() rssRejectParamDto: RssManagementRequestDto,
) {
await this.rssService.rejectRss(params.id, body.description);
await this.rssService.rejectRss(rssRejectParamDto, rssRejectBodyDto);
return ApiResponse.responseWithNoContent('거절이 완료되었습니다.');
}

Expand Down
29 changes: 18 additions & 11 deletions server/src/rss/service/rss.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { FeedCrawlerService } from './feed-crawler.service';
import { RssReadResponseDto } from '../dto/response/rss-all.dto';
import { RssAcceptHistoryResponseDto } from '../dto/response/rss-accept-history.dto';
import { RssRejectHistoryResponseDto } from '../dto/response/rss-reject-history.dto';
import { RssManagementRequestDto } from '../dto/request/rss-management.dto';
import { RejectRssRequestDto } from '../dto/request/rss-reject.dto';

@Injectable()
export class RssService {
Expand All @@ -28,16 +30,16 @@ export class RssService {
private readonly feedCrawlerService: FeedCrawlerService,
) {}

async createRss(rssRegisterDto: RssRegisterRequestDto) {
async createRss(rssRegisterBodyDto: RssRegisterRequestDto) {
const [alreadyURLRss, alreadyURLBlog] = await Promise.all([
this.rssRepository.findOne({
where: {
rssUrl: rssRegisterDto.rssUrl,
rssUrl: rssRegisterBodyDto.rssUrl,
},
}),
this.rssAcceptRepository.findOne({
where: {
rssUrl: rssRegisterDto.rssUrl,
rssUrl: rssRegisterBodyDto.rssUrl,
},
}),
]);
Expand All @@ -50,17 +52,18 @@ export class RssService {
);
}

await this.rssRepository.insertNewRss(rssRegisterDto);
await this.rssRepository.insertNewRss(rssRegisterBodyDto);
}

async readAllRss() {
const rssList = await this.rssRepository.find();
return RssReadResponseDto.toResponseDtoArray(rssList);
}

async acceptRss(id: number) {
async acceptRss(rssAcceptParamDto: RssManagementRequestDto) {
const rssId = rssAcceptParamDto.id;
const rss = await this.rssRepository.findOne({
where: { id },
where: { id: rssId },
});

if (!rss) {
Expand All @@ -73,7 +76,7 @@ export class RssService {
async (manager) => {
const [rssAccept] = await Promise.all([
manager.save(RssAccept.fromRss(rss, blogPlatform)),
manager.delete(Rss, id),
manager.delete(Rss, rssId),
]);
const feeds = await this.feedCrawlerService.loadRssFeeds(
rssAccept.rssUrl,
Expand All @@ -85,9 +88,13 @@ export class RssService {
this.emailService.sendMail(rssAccept, true);
}

async rejectRss(id: number, description: string) {
async rejectRss(
rssRejectParamDto: RssManagementRequestDto,
rssRejectBodyDto: RejectRssRequestDto,
) {
const rssId = rssRejectParamDto.id;
const rss = await this.rssRepository.findOne({
where: { id },
where: { id: rssId },
});

if (!rss) {
Expand All @@ -99,12 +106,12 @@ export class RssService {
manager.remove(rss),
manager.save(RssReject, {
...rss,
description,
description: rssRejectBodyDto.description,
}),
]);
return rejectRss;
});
this.emailService.sendMail(rejectRss, false, description);
this.emailService.sendMail(rejectRss, false, rssRejectBodyDto.description);
}

async readAcceptHistory() {
Expand Down
Loading

0 comments on commit 30c258c

Please sign in to comment.