Skip to content

Commit

Permalink
refactor: Remove unused code and dependencies in invite-response.dto.…
Browse files Browse the repository at this point in the history
…ts and plan.controller.ts
  • Loading branch information
PleBea committed Jul 13, 2024
1 parent 7aaa75b commit 4b0e223
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 123 deletions.
19 changes: 6 additions & 13 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ model User {
UserProfileImage UserProfileImage[]
planId String?
Plan Plan? @relation(fields: [planId], references: [id])
Invite Invite[]
FCMToken String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
Invite Invite?
}

model UserProfileImage {
Expand Down Expand Up @@ -61,18 +61,11 @@ model Place {
Plan Plan @relation(fields: [planId], references: [id])
}

enum InviteStatus {
PENDING
ACCEPTED
REJECTED
}

model Invite {
id String @id @default(uuid())
userId String
User User @relation(fields: [userId], references: [id])
id String @id @default(uuid())
planId String
Plan Plan @relation(fields: [planId], references: [id])
status InviteStatus
createdAt DateTime @default(now())
Plan Plan @relation(fields: [planId], references: [id])
userId String @unique
User User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
}
33 changes: 30 additions & 3 deletions src/modules/plan/dto/invite-response.dto.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
import { $Enums, Invite } from '@prisma/client';
import { Invite, Plan, User } from '@prisma/client';

import { ApiProperty } from '@nestjs/swagger';

import { UserResponseDTO } from 'src/modules/user/dto/user.dto';

import { PlanDTO } from './plan.dto';

export class InviteLinkResponseDTO {
@ApiProperty()
link: string;
}

export class InviteResponseDTO implements Invite {
@ApiProperty()
id: string;
userId: string;

@ApiProperty()
planId: string;
status: $Enums.InviteStatus;

@ApiProperty({
type: UserResponseDTO,
})
User: User;

@ApiProperty()
userId: string;

@ApiProperty({
type: PlanDTO,
})
Plan: Plan;

@ApiProperty()
createdAt: Date;
}
20 changes: 20 additions & 0 deletions src/modules/plan/dto/plan.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { $Enums, Plan } from '@prisma/client';

import { ApiProperty } from '@nestjs/swagger';

export class PlanDTO implements Plan {
@ApiProperty()
id: string;

@ApiProperty()
name: string;

@ApiProperty()
date: string;

@ApiProperty()
status: $Enums.PlanStatus;

@ApiProperty()
createdAt: Date;
}
41 changes: 15 additions & 26 deletions src/modules/plan/plan.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ApiBearerAuth, ApiBody, ApiOkResponse, ApiOperation, ApiTags, ApiUnauth
import { CurrentUser } from 'src/common';

import { CreatePlanDTO } from './dto/create-plan.dto';
import { InviteLinkResponseDTO, InviteResponseDTO } from './dto/invite-response.dto';
import { PlanResponseDTO } from './dto/plan-response.dto';
import { PlanService } from './plan.service';

Expand Down Expand Up @@ -53,42 +54,40 @@ export class PlanController {
return await this.planService.deletePlan(user);
}

@Get('invite')
@Get('invite/:inviteId')
@ApiBearerAuth()
@UseGuards(AuthGuard('access'))
@ApiOperation({ summary: 'Get plan invite' })
@ApiOkResponse({ description: 'Plan invite', type: PlanResponseDTO })
@ApiOkResponse({ description: 'Plan invite', type: InviteResponseDTO })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
async getInvite(@CurrentUser() user: User) {
return await this.planService.getInvite(user);
async getInvite(@CurrentUser() user: User, @Param('inviteId') inviteId: string): Promise<InviteResponseDTO> {
return await this.planService.getInvite(inviteId);
}

@Get('invite/:inviteId')
@Post('invite')
@ApiBearerAuth()
@UseGuards(AuthGuard('access'))
@ApiOperation({ summary: 'Invite user to a plan' })
@ApiOkResponse({ description: 'Plan invite sent', type: InviteLinkResponseDTO })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
async invite(@CurrentUser() user: User): Promise<InviteLinkResponseDTO> {
return { link: await this.planService.invite(user) };
}

@Get('invite/link/:inviteId')
@ApiOperation({ summary: 'Deep link to plan invite' })
@ApiOkResponse({ description: 'Plan invite', type: PlanResponseDTO })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
async getInviteById(@Req() req: Request, @Param('inviteId') inviteId: string, @Res() res: Response) {
if (req.headers['user-agent']?.toLocaleLowerCase().includes('kakaotalk')) {
return res.redirect(
`kakaotalk://web/openExternal?url=${this.configService.get<string>('BACKEND_URL')!}/plan/invite/${inviteId}`,
`kakaotalk://web/openExternal?url=${this.configService.get<string>('BACKEND_URL')!}/plan/invite/link/${inviteId}`,
);
}

res.redirect(`adego-by-seogaemo://invite/${inviteId}`);
}

@Post('invite/:userId')
@ApiBearerAuth()
@UseGuards(AuthGuard('access'))
@ApiOperation({ summary: 'Invite a user to the plan' })
@ApiOkResponse({ description: 'User invited', type: PlanResponseDTO })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
async inviteUser(@CurrentUser() user: User, @Param('userId') userId: string) {
return await this.planService.inviteUser(user, userId);
}

@Put('invite/:inviteId')
@ApiBearerAuth()
@UseGuards(AuthGuard('access'))
Expand All @@ -98,14 +97,4 @@ export class PlanController {
async acceptInvite(@CurrentUser() user: User, @Param('inviteId') inviteId: string) {
return await this.planService.acceptInvite(user, inviteId);
}

@Delete('invite/:inviteId')
@ApiBearerAuth()
@UseGuards(AuthGuard('access'))
@ApiOperation({ summary: 'Decline a plan invite' })
@ApiOkResponse({ description: 'Plan invite reject', type: PlanResponseDTO })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
async rejectInvite(@CurrentUser() user: User, @Param('inviteId') inviteId: string) {
return await this.planService.rejectInvite(user, inviteId);
}
}
158 changes: 77 additions & 81 deletions src/modules/plan/plan.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { InviteStatus, Plan, PlanStatus, User } from '@prisma/client';
import { Plan, PlanStatus, User } from '@prisma/client';
import { DateTime } from 'luxon';

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Cron, CronExpression } from '@nestjs/schedule';

import { FirebaseService } from 'src/common/modules/firebase/firebase.service';
Expand All @@ -17,6 +18,7 @@ export class PlanService {
private readonly prisma: PrismaService,
private readonly firebase: FirebaseService,
private readonly addressService: AddressService,
private readonly configService: ConfigService,
) {}

async getPlan(user: User): Promise<PlanResponseDTO> {
Expand All @@ -39,7 +41,61 @@ export class PlanService {
return { ...plan, isAlarmAvailable: await this.isAlarmAvailable(plan.date) };
}

async createPlan({ id }: User, dto: CreatePlanDTO): Promise<PlanResponseDTO> {
async getInvite(inviteId: string) {
const invite = await this.prisma.invite.findUnique({
where: {
id: inviteId,
},
include: {
Plan: true,
User: true,
},
});

if (!invite) throw new HttpException('Invite not found', HttpStatus.NOT_FOUND);
if (!invite.Plan) throw new HttpException('Plan not found', HttpStatus.NOT_FOUND);

return invite;
}

getInviteLink(inviteId: string) {
return `${this.configService.get('BACKEND_URL')}/plan/invite/link/${inviteId}`;
}

async invite({ id }: User) {
const user = await this.prisma.user.findUnique({
where: {
id,
},
include: {
Plan: true,
Invite: true,
},
});

if (!user) throw new HttpException('User not found', HttpStatus.NOT_FOUND);
if (!user.Plan) throw new HttpException('User does not have a plan', HttpStatus.BAD_GATEWAY);
if (user.Invite) return this.getInviteLink(user.Invite.id);

const invite = await this.prisma.invite.create({
data: {
Plan: {
connect: {
id: user.Plan.id,
},
},
User: {
connect: {
id,
},
},
},
});

return this.getInviteLink(invite.id);
}

async createPlan({ id }: User, dto: CreatePlanDTO) {
if (DateTime.fromISO(dto.date) < DateTime.now())
throw new HttpException('Invalid date', HttpStatus.BAD_REQUEST);

Expand All @@ -55,12 +111,6 @@ export class PlanService {
if (!user) return;
if (user.Plan) throw new HttpException('User already has a plan', HttpStatus.BAD_GATEWAY);

await this.prisma.invite.deleteMany({
where: {
userId: id,
},
});

const place = await this.addressService.getAddressByKeyword(dto.address);

return {
Expand Down Expand Up @@ -145,106 +195,52 @@ export class PlanService {
return { ...res, isAlarmAvailable: await this.isAlarmAvailable(res.date) };
}

async getInvite({ id }: User) {
const invites = await this.prisma.invite.findMany({
where: {
userId: id,
},
include: {
Plan: true,
},
});

return invites;
}

async inviteUser({ id }: User, userId: string) {
async acceptInvite({ id }: User, inviteId: string) {
const user = await this.prisma.user.findUnique({
where: {
id,
},
include: {
Plan: true,
},
});

if (!user) throw new HttpException('User not found', HttpStatus.NOT_FOUND);
if (!user.Plan) throw new HttpException('User does not have a plan', HttpStatus.BAD_GATEWAY);

const targetUser = await this.prisma.user.findUnique({
where: {
id: userId,
},
include: {
Plan: true,
},
});

if (!targetUser) throw new HttpException('Target user not found', HttpStatus.NOT_FOUND);
if (targetUser.planId) throw new HttpException('Target user already has a plan', HttpStatus.BAD_GATEWAY);

return await this.prisma.invite.create({
data: {
userId: userId,
planId: user.planId,
status: InviteStatus.PENDING,
},
});
}

async acceptInvite({ id }: User, inviteId: string) {
const invite = await this.prisma.invite.findUnique({
where: {
id: inviteId,
},
include: {
Plan: true,
User: true,
},
});

if (!invite) throw new HttpException('Invite not found', HttpStatus.NOT_FOUND);
if (invite.userId !== id) throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);

await this.prisma.user.update({
const plan = await this.prisma.plan.findUnique({
where: {
id,
},
data: {
planId: invite.planId,
id: invite.planId,
},
});

await this.prisma.invite.deleteMany({
where: {
userId: id,
include: {
users: true,
},
});

return invite.Plan;
}
if (!plan) throw new HttpException('Plan not found', HttpStatus.NOT_FOUND);
if (plan.users.some((u) => u.id === id))
throw new HttpException('User is already in the plan', HttpStatus.BAD_GATEWAY);

async rejectInvite({ id }: User, inviteId: string) {
const invite = await this.prisma.invite.findUnique({
return await this.prisma.plan.update({
where: {
id: inviteId,
id: plan.id,
},
include: {
Plan: true,
User: true,
data: {
users: {
connect: {
id,
},
},
},
});

if (!invite) throw new HttpException('Invite not found', HttpStatus.NOT_FOUND);
if (invite.userId !== id) throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);

await this.prisma.invite.delete({
where: {
id: inviteId,
include: {
users: true,
place: true,
},
});

return invite.Plan;
}

async isAlarmAvailable(date: string) {
Expand Down

0 comments on commit 4b0e223

Please sign in to comment.