Skip to content

Commit

Permalink
MERGE :: gurdl0525/Tips-API-003-팁-삭제 -> main
Browse files Browse the repository at this point in the history
  • Loading branch information
gurdl0525 committed Jun 11, 2024
2 parents 0f0ce75 + b6b9545 commit 22b33c7
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 16 deletions.
6 changes: 5 additions & 1 deletion src/core/tip/port/tip.in.port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '../../../presentation/tip/dto/tip.request';

export interface WriteTipUseCase {
write(dto: WriteTipRequest, token: string): Promise<void>;
write(dto: WriteTipRequest, token: string): Promise<number>;
}

export interface ModifyTipUseCase {
Expand All @@ -23,3 +23,7 @@ export interface SearchTipUseCase {
export interface ReadRecommendedTipUseCase {
readRecommendedTip(): Promise<object[]>;
}

export interface DeleteTipUseCase {
deleteFromId(id: number, token: string): Promise<void>;
}
6 changes: 5 additions & 1 deletion src/core/tip/port/tip.out.port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ export interface UpdateTipPort {
}

export interface ReadTipPort {
findByIdOrFail(tipId: number): Promise<Tip>;
findByIdOrFail(id: number): Promise<Tip>;

searchTip(dto: SearchTipRequest): Promise<object[]>;

readAllTipByRandom(): Promise<object[] | null>;
}

export interface DeleteTipPort {
deleteById(tipId: number): Promise<void>;
}
2 changes: 2 additions & 0 deletions src/core/tip/tip.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { TipRepository } from '../../domain/tip/tip.repository';
import { User } from '../../domain/user/user.entity';
import { UserRepository } from '../../domain/user/user.repository';
import {
DeleteTipService,
ModifyTipService,
ReadDetailTipService,
ReadRecommendedTipService,
Expand All @@ -32,6 +33,7 @@ import { JwtModule } from '@nestjs/jwt';
{ provide: 'readDetailTip', useClass: ReadDetailTipService },
{ provide: 'searchTip', useClass: SearchTipService },
{ provide: 'readRecommendedTip', useClass: ReadRecommendedTipService },
{ provide: 'deleteTip', useClass: DeleteTipService },
],
})
export class TipModule {}
47 changes: 42 additions & 5 deletions src/core/tip/tip.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
DeleteTipUseCase,
ModifyTipUseCase,
ReadDetailTipUseCase,
ReadRecommendedTipUseCase,
Expand All @@ -11,9 +12,15 @@ import {
WriteTipRequest,
} from '../../presentation/tip/dto/tip.request';
import { Tip } from '../../domain/tip/tip.entity';
import { ForbiddenException, HttpException, Inject } from '@nestjs/common';
import {
ForbiddenException,
HttpException,
Inject,
NotFoundException,
} from '@nestjs/common';
import { ReadCurrentUserPort } from '../auth/port/auth.out.port';
import { ReadTipPort, SaveTipPort, UpdateTipPort } from './port/tip.out.port';
import { DeleteTipPort, ReadTipPort, SaveTipPort, UpdateTipPort } from './port/tip.out.port';
import { JwtAdapter } from '../../infrastructure/jwt/jwt.adapter';

export class WriteTipService implements WriteTipUseCase {
constructor(
Expand All @@ -23,12 +30,14 @@ export class WriteTipService implements WriteTipUseCase {
private readonly saveTipPort: SaveTipPort,
) {}

write = async (dto: WriteTipRequest, token: string): Promise<void> => {
write = async (dto: WriteTipRequest, token: string): Promise<number> => {
const user = await this.readCurrentUserPort.verifyUser(token);

const tip = new Tip(dto.title, dto.content, user);
const tip = await this.saveTipPort.save(
new Tip(dto.title, dto.content, user),
);

await this.saveTipPort.save(tip);
return tip.id;
};
}

Expand Down Expand Up @@ -108,3 +117,31 @@ export class ReadRecommendedTipService implements ReadRecommendedTipUseCase {
return data;
};
}

export class DeleteTipService implements DeleteTipUseCase {
constructor(
@Inject('tip out port')
private readonly readTipPort: ReadTipPort,
@Inject('tip out port')
private readonly deleteTipPort: DeleteTipPort,
@Inject('jwt')
private readonly readCurrentUserPort: ReadCurrentUserPort,
) {}

deleteFromId = async (tipId: number, token: string): Promise<void> => {
const user = await this.readCurrentUserPort.verifyUser(token);

console.log(tipId);

const tip = await this.readTipPort.findByIdOrFail(tipId);
console.log(tip);

if (user.id != tip.writer_id) {
throw new ForbiddenException('Permission denied for this tip');
}

console.log(tip.id);

await this.deleteTipPort.deleteById(tip.id);
};
}
17 changes: 14 additions & 3 deletions src/domain/tip/tip.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Tip } from './tip.entity';
import {
DeleteTipPort,
ReadTipPort,
SaveTipPort,
UpdateTipPort,
Expand All @@ -13,7 +14,9 @@ import {
} from 'src/presentation/tip/dto/tip.request';

@Injectable()
export class TipRepository implements SaveTipPort, UpdateTipPort, ReadTipPort {
export class TipRepository
implements SaveTipPort, UpdateTipPort, ReadTipPort, DeleteTipPort
{
constructor(
@InjectRepository(Tip) private readonly tipEntity: Repository<Tip>,
) {}
Expand All @@ -26,8 +29,8 @@ export class TipRepository implements SaveTipPort, UpdateTipPort, ReadTipPort {
await this.tipEntity.update(tipId, dto);
};

findByIdOrFail = async (tipId: number): Promise<Tip> => {
const tip = await this.tipEntity.findOneBy({ id: tipId });
findByIdOrFail = async (id: number): Promise<Tip> => {
const tip = await this.tipEntity.findOneBy({ id });

if (!tip) throw new NotFoundException('Tip Not Found');

Expand Down Expand Up @@ -67,4 +70,12 @@ export class TipRepository implements SaveTipPort, UpdateTipPort, ReadTipPort {
.limit(18)
.getRawMany();
};

deleteById = async (tipId: number): Promise<void> => {
await this.tipEntity
.createQueryBuilder()
.delete()
.where('tbl_tip.id = :id', { id: tipId })
.execute();
};
}
38 changes: 32 additions & 6 deletions src/presentation/tip/tip.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {
BadRequestException,
Body,
Controller,
Delete,
Get,
Headers,
Inject,
Param,
Patch,
Post,
Query,
Req,
Res,
UnauthorizedException,
} from '@nestjs/common';
Expand All @@ -17,15 +18,15 @@ import {
SearchTipRequest,
WriteTipRequest,
} from './dto/tip.request';
import { Response } from 'express';
import { Request, Response } from 'express';
import {
DeleteTipUseCase,
ModifyTipUseCase,
ReadDetailTipUseCase,
ReadRecommendedTipUseCase,
SearchTipUseCase,
WriteTipUseCase,
} from '../../core/tip/port/tip.in.port';
import { SortType } from 'src/domain/post/post.entity';

@Controller('tip')
export class TipController {
Expand All @@ -40,6 +41,8 @@ export class TipController {
private readonly searchTipUseCase: SearchTipUseCase,
@Inject('readRecommendedTip')
private readonly readRecommendedTipUseCase: ReadRecommendedTipUseCase,
@Inject('deleteTip')
private readonly deleteTipUseCase: DeleteTipUseCase,
) {}

@Get('/search')
Expand All @@ -58,6 +61,20 @@ export class TipController {
.send();
}

@Delete('/:tipId')
async deleteTip(
@Headers('Authorization') token: string,
@Param('tipId') tipId: number,
@Res() res: Response,
): Promise<Response> {
if (!token || !tipId) {
throw new UnauthorizedException('Permission denied');
}
await this.deleteTipUseCase.deleteFromId(tipId, token);

return res.sendStatus(200);
}

@Get('/recommend')
async readRecommended(@Res() res: Response): Promise<Response> {
return res
Expand All @@ -72,15 +89,24 @@ export class TipController {
async writeTip(
@Body() dto: WriteTipRequest,
@Headers('Authorization') token: string,
@Req() req: Request,
@Res() res: Response,
): Promise<Response> {
if (!token) {
throw new UnauthorizedException('Permission denied');
}

await this.writeTipUseCase.write(dto, token);
const tipId = await this.writeTipUseCase.write(dto, token);

let location: string;

return res.sendStatus(201);
if (req.hostname != 'localhost') {
location = `${req.protocol}://${req.hostname}/tip/${tipId}`;
} else {
location = `${req.protocol}://${req.hostname}:${process.env.PORT}/tip/${tipId}`;
}

return res.location(location).sendStatus(201);
}

@Patch('/:tipId')
Expand All @@ -105,7 +131,7 @@ export class TipController {
@Param('tipId') tipId: number,
@Res() res: Response,
): Promise<Response> {
if (!token) {
if (!token || !tipId) {
throw new UnauthorizedException('Permission denied');
}

Expand Down

0 comments on commit 22b33c7

Please sign in to comment.