1. Follower Count μ¦κ° & κ°μ - 1
user μν°ν°μ νλ‘μ°, νλ‘μ μ 컬λΌμ μΆκ°ν΄μ€λ€.
users.entity.ts
1@Column({ default: 0 })2followerCount: number34@Column({ default: 0 })5followeeCount: number
users 컨νΈλ‘€λ¬
users/users.controller.ts
1import { QueryRunner as QR } from 'typeorm'2// λλ¨Έμ§ import μλ΅34// **** νλ‘μ° μμ² μΉμΈ5@Patch('follow/:id/confirm')6@UseInterceptors(TransactionInterceptor)7async patchFollowConfirm(8@User() user: UsersModel, //9@Param('id', ParseIntPipe) followerId: number,10@QueryRunner() qr: QR,11) {12await this.usersService.confirmFollow(followerId, user.id, qr)13await this.usersService.incrementFollowerCount(user.id, qr)14return true15}1617// **** νλ‘μ° μμ² μμ 18@Delete('follow/:id')19async deleteFollow(20@User() user: UsersModel, //21@Param('id', ParseIntPipe) followeeId: number,22@QueryRunner() qr: QR,23) {24await this.usersService.deleteFollow(user.id, followeeId, qr)25await this.usersService.decrementFollowerCount(followeeId, qr)26return true27}
users μλΉμ€
users/users.service.ts
1@Injectable()2export class UsersService {3// μλ΅45getUsersRepository(qr?: QueryRunner) {6return qr //7? qr.manager.getRepository<UsersModel>(UsersModel)8: this.usersRepository9}1011getUserFollowRepository(qr?: QueryRunner) {12return qr //13? qr.manager.getRepository<UserFollowersModel>(UserFollowersModel)14: this.userFollowersRepository15}1617// μλ΅1819// **** 4) νλ‘μ° μμ²20async followUser(followerId: number, followeeId: number, qr?: QueryRunner) {21const userFollowersRepository = this.getUserFollowRepository(qr)2223await userFollowersRepository.save({24follower: { id: followerId },25followee: { id: followeeId },26})2728return true29}3031// **** 5) νλ‘μλ€ μ‘°ν32// μλ΅3334// **** νλ‘μ° μμ² μΉμΈ35async confirmFollow(followerId: number, followeeId: number, qr?: QueryRunner) {36const userFollowersRepository = this.getUserFollowRepository(qr)3738const existing = await userFollowersRepository.findOne({39where: {40follower: { id: followerId },41followee: { id: followeeId },42},43relations: {44follower: true,45followee: true,46},47})4849if (!existing) {50throw new BadRequestException('μ‘΄μ¬νμ§ μλ νλ‘μ° μμ²μ λλ€!')51}5253await userFollowersRepository.save({54...existing,55isConfirmed: true,56})5758return true59}6061// **** νλ‘μ° μμ² μμ 62async deleteFollow(followerId: number, followeeId: number, qr?: QueryRunner) {63const userFollowersRepository = this.getUserFollowRepository(qr)6465await userFollowersRepository.delete({66follower: {67id: followerId,68},69followee: {70id: followeeId,71},72})7374return true75}7677async incrementFollowerCount(userId: number, qr?: QueryRunner) {78const userRepository = this.getUsersRepository(qr)7980await userRepository.increment(81{ id: userId }, //82'followerCount',831,84)85}8687async decrementFollowerCount(userId: number, qr?: QueryRunner) {88const userRepository = this.getUsersRepository(qr)8990await userRepository.decrement(91{ id: userId }, //92'followerCount',931,94)95}96}
2. Follower Count μ¦κ° & κ°μ - 2
posts μλΉμ€μ λκΈ μλ₯Ό νμνλ κΈ°λ₯μ μΆκ°νλ€.
posts.service.ts
1// **** ν¬μ€νΈ λκΈ μ μ¦κ°2async incrementCommentCount(postId: number, qr?: QueryRunner) {3const repository = this.getRepository(qr)45await repository.increment({ id: postId }, 'commentCount', 1)6}78// **** ν¬μ€νΈ λκΈ μ κ°μ9async decrementCommentCount(postId: number, qr?: QueryRunner) {10const repository = this.getRepository(qr)11await repository.decrement({ id: postId }, 'commentCount', 1)12}
3. Comment Count
comments μλΉμ€μ queryRunnerλ₯Ό μΆκ°νλ€.
comments.service.ts
1getRepository(qr?: QueryRunner) {2return qr //3? qr.manager.getRepository<CommentsModel>(CommentsModel)4: this.commentsRepository5}67// **** (3) λκΈ μμ±8async createComment(9dto: CreateCommentsDto, //10postId: number,11author: UsersModel,12qr?: QueryRunner,13) {14const repository = this.getRepository(qr)1516return repository.save({17...dto,18post: { id: postId },19author,20})21}2223// **** (5) λκΈ μμ 24async deleteComment(id: number, qr?: QueryRunner) {25const repository = this.getRepository(qr)2627const comment = await repository.findOne({28where: { id },29})3031if (!comment) {32throw new BadRequestException('μ‘΄μ¬νμ§ μλ λκΈμ λλ€.')33}3435await repository.delete(id)3637return id38}
comments 컨νΈλ‘€λ¬λ λ€μκ³Ό κ°μ΄ μμ νλ€.
comments.controller.ts
1@Controller('posts/:postId/comments')2export class CommentsController {3constructor(private readonly commentsService: CommentsService, private readonly postsService: PostsService) {}45// μλ΅67// **** (3) λκΈ μμ±8@Post()9@UseInterceptors(TransactionInterceptor)10async postComment(11@Param('postId', ParseIntPipe) postId: number,12@Body() body: CreateCommentsDto,13@User() user: UsersModel,14@QueryRunner() qr: QR,15) {16const resp = await this.commentsService.createComment(body, postId, user, qr)1718await this.postsService.incrementCommentCount(postId, qr)1920return resp21}2223// μλ΅2425// **** (5) λκΈ μμ 26@Delete(':commentId')27@UseGuards(IsCommentMineOrAdminGuard)28@UseInterceptors(TransactionInterceptor)29async deleteComment(30@Param('commentId', ParseIntPipe) commentId: number, //31@Param('postId', ParseIntPipe) postId: number,32@QueryRunner() qr: QR,33) {34const resp = await this.commentsService.deleteComment(commentId, qr)3536await this.postsService.decrementCommentCount(postId, qr)3738return resp39}40}