Skip to content

Commit

Permalink
feat: Add generating new meets and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
lsjbh45 committed Nov 26, 2023
1 parent 2c583c6 commit 6229d96
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 12 deletions.
76 changes: 76 additions & 0 deletions src/apis/meet/meet.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
Query,
BadRequestException,
Param,
Post,
Body,
} from '@nestjs/common';
import { FcmService } from '../fcm/fcm.service';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
Expand All @@ -14,8 +16,11 @@ import { RoleGuard } from '../auth/guard/role.guard';
import { Role } from 'src/lib/enums/user.role.enum';
import {
AuthUserDto,
MeetCommentRequestDto,
MeetCommentResponseDto,
MeetDetailRequestDto,
MeetDetailResponseDto,
MeetOpenRequestDto,
MeetRequestDto,
MeetResponseDto,
PaginationDto,
Expand Down Expand Up @@ -116,4 +121,75 @@ export class MeetController {
const meet = await this.meetService.getMeetById(id);
return MeetDetailResponseDto.of(meet);
}

@Get('/:id/comment')
@UseGuards(JwtAuthGuard, RoleGuard(Role.USER))
@ApiOperation({ summary: '모임에 대한 댓글 목록을 반환' })
@ApiBearerAuth()
async getComments(
@Param() payload: MeetDetailRequestDto,
): Promise<MeetCommentResponseDto[]> {
const { id: meetId } = payload;

const comments = await this.meetService.getCommentsByMeetId(meetId);
return comments.map(MeetCommentResponseDto.of);
}

@Post()
@UseGuards(JwtAuthGuard, RoleGuard(Role.USER))
@ApiOperation({ summary: '새로운 모임을 개설' })
@ApiBearerAuth()
async addMeet(
@AuthUser() user: AuthUserDto,
@Body() payload: MeetOpenRequestDto,
): Promise<void> {
const { id: hostId } = user;
const { tagId } = payload;

const { id } = await this.meetService.addMeet({ hostId, ...payload });

const targets = await this.userService.getUsersByTagId(tagId);

await Promise.all(
targets
.filter((target) => target.id !== hostId)
.map((target) =>
this.fcmService.sendMessageNewMeet(target.fcmToken, id),
),
);
}

@Post('/:id/comment')
@UseGuards(JwtAuthGuard, RoleGuard(Role.USER))
@ApiOperation({ summary: '모임에 대한 댓글을 작성' })
@ApiBearerAuth()
async addComment(
@AuthUser() user: AuthUserDto,
@Param() params: MeetDetailRequestDto,
@Body() payload: MeetCommentRequestDto,
): Promise<void> {
const { id: meetId } = params;
const { id: userId } = user;

const meet = await this.meetService.getMeetById(meetId);
if (!meet) {
throw new BadRequestException('존재하지 않는 모임입니다.');
}

const { host, participations } = meet;
const targets = [host, ...participations.map((part) => part.user)];

if (!targets.map((target) => target.id).includes(userId)) {
throw new BadRequestException('모임에 참여하지 않은 사용자입니다.');
}
await this.meetService.addComment({ meetId, userId, ...payload });

await Promise.all(
targets
.filter((target) => target.id !== userId)
.map((target) =>
this.fcmService.sendMessageNewReply(target.fcmToken, meetId),
),
);
}
}
18 changes: 11 additions & 7 deletions src/apis/meet/meet.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Meet, Comment } from 'src/entities';
import { FindOptionsWhere, Repository } from 'typeorm';
import { AuthUser } from 'src/lib/decorators/auth.user.decorator';
import { FindOptionsPage } from 'src/lib/utils/pagination.util';

@Injectable()
Expand Down Expand Up @@ -33,13 +32,18 @@ export class MeetService {
});
}

async getComment(@AuthUser() user, meetId: number): Promise<Comment[]> {
const { id: userId } = user;
async getCommentsByMeetId(meetId: number): Promise<Comment[]> {
return this.commentRepository.find({
where: {
meetId,
userId,
},
where: { meetId },
relations: { user: {} },
});
}

async addMeet(meet: Partial<Meet>): Promise<Meet> {
return this.meetRepository.create(meet).save();
}

async addComment(comment: Partial<Comment>): Promise<void> {
await this.commentRepository.create(comment).save();
}
}
6 changes: 6 additions & 0 deletions src/apis/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export class UserService {
});
}

async getUsersByTagId(tagId: number): Promise<User[]> {
return this.userRepository.find({
where: { subscriptions: { tagId } },
});
}

async getUserByIdOrFail(id: number): Promise<User> {
return this.userRepository.findOneOrFail({ where: { id } });
}
Expand Down
2 changes: 2 additions & 0 deletions src/dtos/meet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { MeetCommentRequestDto } from './meet.comment.req.dto';
import { MeetCommentResponseDto } from './meet.comment.res.dto';
import { MeetDetailRequestDto } from './meet.detail.req.dto';
import { MeetDetailResponseDto } from './meet.detail.res.dto';
import { MeetOpenRequestDto } from './meet.open.req.dto';

export {
MeetResponseDto,
MeetDetailResponseDto,
MeetCommentRequestDto,
MeetRequestDto,
MeetDetailRequestDto,
MeetOpenRequestDto,
MeetCommentResponseDto,
};
5 changes: 4 additions & 1 deletion src/dtos/meet/meet.comment.req.dto.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { IsString } from 'class-validator';

export class MeetCommentRequestDto {
meetId: number;
@IsString()
body: string;
}
8 changes: 4 additions & 4 deletions src/dtos/meet/meet.comment.res.dto.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Comment } from '../../entities/comment.entity';
import { UserResponseDto } from '../user';

export class MeetCommentResponseDto {
id: number;
userId: number;
meetId: number;
user: UserResponseDto;
body: string;
createdAt: Date;

static of(comment: Comment): MeetCommentResponseDto {
const { id, userId, meetId, body, createdAt } = comment;
return { id, userId, meetId, body, createdAt };
const { id, user, body, createdAt } = comment;
return { id, user: UserResponseDto.of(user), body, createdAt };
}
}
53 changes: 53 additions & 0 deletions src/dtos/meet/meet.open.req.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Transform } from 'class-transformer';
import {
IsBoolean,
IsDate,
IsEnum,
IsNumber,
IsOptional,
IsString,
Max,
Min,
MinDate,
} from 'class-validator';
import { Gender } from 'src/lib/enums';

export class MeetOpenRequestDto {
@IsString()
title: string;

@IsString()
body: string;

@IsNumber()
tagId: number;

@IsNumber()
@Min(2)
maxParticipants: number;

@IsDate()
@Transform(({ value }) => new Date(value))
@MinDate(new Date())
meetTime: Date;

@IsBoolean()
isOnline: boolean;

@IsString()
location: string;

@IsEnum(Gender)
@IsOptional()
gender?: Gender;

@IsNumber()
@IsOptional()
@Min(19)
minAge?: number;

@IsNumber()
@IsOptional()
@Max(99)
maxAge?: number;
}

0 comments on commit 6229d96

Please sign in to comment.