Skip to content

Commit 4474640

Browse files
authored
Merge pull request #428 from boostcampwm-2024/feat/rss-remove-get
✨ feat: RSS 삭제 신청 조회 API 구현
2 parents 15d0982 + 1709249 commit 4474640

File tree

15 files changed

+297
-29
lines changed

15 files changed

+297
-29
lines changed

docker-compose/init.sql

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,14 @@ CREATE TABLE `comment` (
130130

131131
CREATE TABLE `likes` (
132132
`id` int NOT NULL AUTO_INCREMENT,
133+
`like_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
133134
`feed_id` int NOT NULL,
134135
`user_id` int NOT NULL,
135-
`like_date` datetime NOT NULL,
136136
PRIMARY KEY (`id`),
137-
UNIQUE KEY `UQ_likes_user_feed` (`user_id`,`feed_id`),
138-
KEY `FK_like_feed` (`feed_id`),
139-
CONSTRAINT `FK_like_feed` FOREIGN KEY (`feed_id`) REFERENCES `feed` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
140-
CONSTRAINT `FK_like_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
137+
UNIQUE KEY `IDX_0be1d6ca115f56ed76c65e6bda` (`user_id`,`feed_id`),
138+
KEY `FK_85b0dbd1e7836d0f8cdc38fe830` (`feed_id`),
139+
CONSTRAINT `FK_3f519ed95f775c781a254089171` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
140+
CONSTRAINT `FK_85b0dbd1e7836d0f8cdc38fe830` FOREIGN KEY (`feed_id`) REFERENCES `feed` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
141141
);
142142

143143
-- denamu.provider definition
@@ -155,6 +155,18 @@ CREATE TABLE `provider` (
155155
CONSTRAINT `FK_d3d18186b602240b93c9f1621ea` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
156156
);
157157

158+
-- denamu.rss_remove definition
159+
160+
CREATE TABLE `rss_remove` (
161+
`id` int NOT NULL AUTO_INCREMENT,
162+
`request_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
163+
`reason` text COLLATE utf8mb4_unicode_ci NOT NULL,
164+
`blog_id` int NOT NULL,
165+
PRIMARY KEY (`id`),
166+
UNIQUE KEY `REL_69e45fd3ff04dac43a89e1951e` (`blog_id`),
167+
CONSTRAINT `FK_69e45fd3ff04dac43a89e1951e4` FOREIGN KEY (`blog_id`) REFERENCES `rss_accept` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
168+
);
169+
158170
-- denamu.admin insert data
159171

160172
INSERT INTO admin (login_id, password) VALUES
@@ -371,11 +383,16 @@ INSERT INTO comment(comment, date, feed_id, user_id) VALUES
371383

372384
-- denamu.activity insert data
373385

374-
-- INSERT INTO activity (activity_date, view_count, user_id) VALUES
375-
-- ();
386+
INSERT INTO activity (activity_date, view_count, user_id) VALUES
387+
('2025-07-01 11:48:00', 1, 1);
376388

377389
-- denamu.like insert data
378390

379391
INSERT INTO likes(feed_id, user_id, like_date) VALUES
380392
(94,1,'2025-06-13 17:47:05'),
381-
(95,1,'2025-06-13 17:47:07');
393+
(95,1,'2025-06-13 17:47:07');
394+
395+
-- denamu.rss_remove insert data
396+
397+
INSERT INTO rss_remove(request_date, reason, blog_id) VALUES
398+
('2025-07-01 11:48:00', 'example reason', 1);

server/src/admin/entity/admin.entity.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
22

3-
abstract class UserInformation extends BaseEntity {
3+
@Entity({
4+
name: 'admin',
5+
})
6+
export class Admin extends BaseEntity {
47
@PrimaryGeneratedColumn()
58
id: number;
69

@@ -17,8 +20,3 @@ abstract class UserInformation extends BaseEntity {
1720
})
1821
password: string;
1922
}
20-
21-
@Entity({
22-
name: 'admin',
23-
})
24-
export class Admin extends UserInformation {}

server/src/common/swagger/swagger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export function setupSwagger(app: INestApplication) {
1212
.setVersion('1.0')
1313
.addTag('Admin', '관리자 전용 API')
1414
.addTag('Feed', '피드 관리와 검색 관련 API')
15-
.addTag('RSS', '관리자 전용 API')
15+
.addTag('RSS', 'RSS 관련 API')
1616
.addTag('Statistic', '통계 정보 조회 API')
1717
.addTag('User', '사용자 관리와 인증 관련 API')
1818
.addTag('OAuth', 'OAuth 관련 API')

server/src/migration/1749798966642-CreateLike.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ export class CreateLike1749798966642 implements MigrationInterface {
44
public async up(queryRunner: QueryRunner): Promise<void> {
55
await queryRunner.query(
66
`
7-
CREATE TABLE likes (
8-
id INT NOT NULL AUTO_INCREMENT,
9-
feed_id INT NOT NULL,
10-
user_id INT NOT NULL,
11-
like_date DATETIME NOT NULL,
12-
PRIMARY KEY (id),
13-
UNIQUE KEY UQ_likes_user_feed (user_id, feed_id),
14-
CONSTRAINT FK_like_feed FOREIGN KEY (feed_id) REFERENCES \`feed\`(id) ON UPDATE CASCADE ON DELETE CASCADE,
15-
CONSTRAINT FK_like_user FOREIGN KEY (user_id) REFERENCES \`user\`(id) ON UPDATE CASCADE ON DELETE CASCADE
7+
CREATE TABLE \`likes\` (
8+
\`id\` int NOT NULL AUTO_INCREMENT,
9+
\`like_date\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
10+
\`feed_id\` int NOT NULL,
11+
\`user_id\` int NOT NULL,
12+
PRIMARY KEY (\`id\`),
13+
UNIQUE KEY \`IDX_0be1d6ca115f56ed76c65e6bda\` (\`user_id\`,\`feed_id\`),
14+
KEY \`FK_85b0dbd1e7836d0f8cdc38fe830\` (\`feed_id\`),
15+
CONSTRAINT \`FK_3f519ed95f775c781a254089171\` FOREIGN KEY (\`user_id\`) REFERENCES \`user\` (\`id\`) ON DELETE CASCADE ON UPDATE CASCADE,
16+
CONSTRAINT \`FK_85b0dbd1e7836d0f8cdc38fe830\` FOREIGN KEY (\`feed_id\`) REFERENCES \`feed\` (\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
1617
);`,
1718
);
1819
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
3+
export class CreateRssRemove1751373592194 implements MigrationInterface {
4+
public async up(queryRunner: QueryRunner): Promise<void> {
5+
await queryRunner.query(
6+
`CREATE TABLE \`rss_remove\` (
7+
\`id\` int NOT NULL AUTO_INCREMENT,
8+
\`request_date\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
9+
\`reason\` text COLLATE utf8mb4_unicode_ci NOT NULL,
10+
\`blog_id\` int NOT NULL,
11+
PRIMARY KEY (\`id\`),
12+
UNIQUE KEY \`REL_69e45fd3ff04dac43a89e1951e\` (\`blog_id\`),
13+
CONSTRAINT \`FK_69e45fd3ff04dac43a89e1951e4\` FOREIGN KEY (\`blog_id\`) REFERENCES \`rss_accept\` (\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
14+
);
15+
`,
16+
);
17+
}
18+
19+
public async down(queryRunner: QueryRunner): Promise<void> {
20+
await queryRunner.query('DROP TABLE rss_remove;');
21+
}
22+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
3+
export class Migration1752060032219 implements MigrationInterface {
4+
public async up(queryRunner: QueryRunner): Promise<void> {
5+
await queryRunner.query('ALTER TABLE likes DROP FOREIGN KEY FK_like_feed;');
6+
await queryRunner.query('ALTER TABLE likes DROP FOREIGN KEY FK_like_user;');
7+
await queryRunner.query('ALTER TABLE likes DROP INDEX UQ_likes_user_feed;');
8+
9+
await queryRunner.query(
10+
'ALTER TABLE likes ADD CONSTRAINT FK_85b0dbd1e7836d0f8cdc38fe830 FOREIGN KEY (feed_id) REFERENCES feed(id);',
11+
);
12+
await queryRunner.query(
13+
'ALTER TABLE likes ADD CONSTRAINT FK_3f519ed95f775c781a254089171 FOREIGN KEY (user_id) REFERENCES user(id);',
14+
);
15+
await queryRunner.query(
16+
'ALTER TABLE likes ADD CONSTRAINT IDX_0be1d6ca115f56ed76c65e6bda UNIQUE (`user_id`,`feed_id`);',
17+
);
18+
}
19+
20+
public async down(queryRunner: QueryRunner): Promise<void> {
21+
await queryRunner.query(
22+
'ALTER TABLE likes DROP FOREIGN KEY FK_85b0dbd1e7836d0f8cdc38fe830;',
23+
);
24+
await queryRunner.query(
25+
'ALTER TABLE likes DROP FOREIGN KEY FK_3f519ed95f775c781a254089171;',
26+
);
27+
await queryRunner.query(
28+
'ALTER TABLE likes DROP INDEX IDX_0be1d6ca115f56ed76c65e6bda;',
29+
);
30+
31+
await queryRunner.query(
32+
'ALTER TABLE likes ADD CONSTRAINT FK_like_feed FOREIGN KEY (feed_id) REFERENCES feed(id);',
33+
);
34+
await queryRunner.query(
35+
'ALTER TABLE likes ADD CONSTRAINT FK_like_user FOREIGN KEY (user_id) REFERENCES user(id);',
36+
);
37+
await queryRunner.query(
38+
'ALTER TABLE likes ADD CONSTRAINT UQ_likes_user_feed UNIQUE (`user_id`,`feed_id`);',
39+
);
40+
}
41+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { applyDecorators } from '@nestjs/common';
2+
import { ApiOkResponse, ApiOperation } from '@nestjs/swagger';
3+
4+
export function ApiReadDeleteRequestList() {
5+
return applyDecorators(
6+
ApiOperation({ summary: 'RSS 취소 신청 조회 API' }),
7+
ApiOkResponse({
8+
description: 'RSS 취소 신청 성공시',
9+
schema: {
10+
properties: {
11+
message: {
12+
type: 'string',
13+
},
14+
data: {
15+
type: 'array',
16+
items: {
17+
type: 'object',
18+
properties: {
19+
id: {
20+
type: 'number',
21+
},
22+
blog: {
23+
type: 'object',
24+
properties: {
25+
id: {
26+
type: 'number',
27+
},
28+
name: {
29+
type: 'string',
30+
},
31+
userName: {
32+
type: 'string',
33+
},
34+
email: {
35+
type: 'string',
36+
},
37+
rssUrl: {
38+
type: 'string',
39+
},
40+
blogPlatform: {
41+
type: 'string',
42+
},
43+
},
44+
},
45+
date: {
46+
type: 'date',
47+
},
48+
reason: {
49+
type: 'string',
50+
},
51+
},
52+
},
53+
},
54+
},
55+
},
56+
example: {
57+
message: 'RSS 삭제 요청을 조회하였습니다.',
58+
data: [
59+
{
60+
id: 1,
61+
date: '2025-07-01T02:48:00.000Z',
62+
reason: 'example reason',
63+
blog: {
64+
id: 1,
65+
name: 'example',
66+
userName: 'example',
67+
email: 'example@example.com',
68+
rssUrl: 'example.com',
69+
blogPlatform: 'example',
70+
},
71+
},
72+
],
73+
},
74+
}),
75+
);
76+
}

server/src/rss/controller/rss.controller.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Controller,
44
Get,
55
HttpCode,
6+
HttpStatus,
67
Param,
78
Post,
89
UseGuards,
@@ -20,6 +21,7 @@ import { ApiReadAcceptHistory } from '../api-docs/readAcceptHistoryRss.api-docs'
2021
import { ApiReadRejectHistory } from '../api-docs/readRejectHistoryRss.api-docs';
2122
import { ApiReadAllRss } from '../api-docs/readAllRss.api-docs';
2223
import { ApiRejectRss } from '../api-docs/rejectRss.api-docs';
24+
import { ApiReadDeleteRequestList } from '../api-docs/readDeleteRequest.api-docs';
2325

2426
@ApiTags('RSS')
2527
@Controller('rss')
@@ -28,14 +30,15 @@ export class RssController {
2830

2931
@ApiCreateRss()
3032
@Post()
33+
@HttpCode(HttpStatus.CREATED)
3134
async createRss(@Body() rssRegisterBodyDto: RssRegisterRequestDto) {
3235
await this.rssService.createRss(rssRegisterBodyDto);
3336
return ApiResponse.responseWithNoContent('신청이 완료되었습니다.');
3437
}
3538

3639
@ApiReadAllRss()
3740
@Get()
38-
@HttpCode(200)
41+
@HttpCode(HttpStatus.OK)
3942
async readAllRss() {
4043
return ApiResponse.responseWithData(
4144
'Rss 조회 완료',
@@ -46,7 +49,7 @@ export class RssController {
4649
@ApiAcceptRss()
4750
@UseGuards(CookieAuthGuard)
4851
@Post('accept/:id')
49-
@HttpCode(201)
52+
@HttpCode(HttpStatus.CREATED)
5053
async acceptRss(@Param() rssAcceptParamDto: RssManagementRequestDto) {
5154
await this.rssService.acceptRss(rssAcceptParamDto);
5255
return ApiResponse.responseWithNoContent('승인이 완료되었습니다.');
@@ -55,7 +58,7 @@ export class RssController {
5558
@ApiRejectRss()
5659
@UseGuards(CookieAuthGuard)
5760
@Post('reject/:id')
58-
@HttpCode(201)
61+
@HttpCode(HttpStatus.CREATED)
5962
async rejectRss(
6063
@Body() rssRejectBodyDto: RejectRssRequestDto,
6164
@Param() rssRejectParamDto: RssManagementRequestDto,
@@ -67,6 +70,7 @@ export class RssController {
6770
@ApiReadAcceptHistory()
6871
@UseGuards(CookieAuthGuard)
6972
@Get('history/accept')
73+
@HttpCode(HttpStatus.OK)
7074
async readAcceptHistory() {
7175
return ApiResponse.responseWithData(
7276
'승인 기록 조회가 완료되었습니다.',
@@ -77,10 +81,22 @@ export class RssController {
7781
@ApiReadRejectHistory()
7882
@UseGuards(CookieAuthGuard)
7983
@Get('history/reject')
84+
@HttpCode(HttpStatus.OK)
8085
async readRejectHistory() {
8186
return ApiResponse.responseWithData(
8287
'RSS 거절 기록을 조회하였습니다.',
8388
await this.rssService.readRejectHistory(),
8489
);
8590
}
91+
92+
@ApiReadDeleteRequestList()
93+
@UseGuards(CookieAuthGuard)
94+
@Get('remove')
95+
@HttpCode(HttpStatus.OK)
96+
async readDeleteRequestList() {
97+
return ApiResponse.responseWithData(
98+
'RSS 삭제 요청을 조회하였습니다.',
99+
await this.rssService.readRemoveList(),
100+
);
101+
}
86102
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {
2+
BaseEntity,
3+
Column,
4+
CreateDateColumn,
5+
Entity,
6+
JoinColumn,
7+
OneToOne,
8+
PrimaryGeneratedColumn,
9+
} from 'typeorm';
10+
import { RssAccept } from './rss.entity';
11+
12+
@Entity({
13+
name: 'rss_remove',
14+
})
15+
export class RssRemoveRequest extends BaseEntity {
16+
@PrimaryGeneratedColumn()
17+
id: number;
18+
19+
@OneToOne(() => RssAccept, {
20+
nullable: false,
21+
onUpdate: 'CASCADE',
22+
onDelete: 'CASCADE',
23+
})
24+
@JoinColumn({
25+
name: 'blog_id',
26+
})
27+
blog: RssAccept;
28+
29+
@CreateDateColumn({
30+
name: 'request_date',
31+
})
32+
date: Date;
33+
34+
@Column({
35+
type: 'text',
36+
})
37+
reason: string;
38+
}

server/src/rss/entity/rss.entity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from 'typeorm';
99
import { Feed } from '../../feed/entity/feed.entity';
1010

11-
export abstract class RssInformation extends BaseEntity {
11+
export class RssInformation extends BaseEntity {
1212
@PrimaryGeneratedColumn()
1313
id: number;
1414

0 commit comments

Comments
 (0)