-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from se-gam/feat/notice
feat: 공지사항 API 추가
- Loading branch information
Showing
12 changed files
with
339 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,4 +42,5 @@ jobs: | |
git pull origin dev | ||
yarn install | ||
yarn build | ||
yarn db:save:dev | ||
dotenv -e .dev.env -- pm2 restart main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
-- CreateTable | ||
CREATE TABLE "notice" ( | ||
"id" INTEGER NOT NULL, | ||
"title" TEXT NOT NULL, | ||
"content" TEXT NOT NULL, | ||
"is_popup" BOOLEAN NOT NULL DEFAULT false, | ||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"deleted_at" TIMESTAMP(3), | ||
|
||
CONSTRAINT "notice_pkey" PRIMARY KEY ("id") | ||
); |
4 changes: 4 additions & 0 deletions
4
prisma/migrations/20250105133040_set_notice_id_default/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
-- AlterTable | ||
CREATE SEQUENCE notice_id_seq; | ||
ALTER TABLE "notice" ALTER COLUMN "id" SET DEFAULT nextval('notice_id_seq'); | ||
ALTER SEQUENCE notice_id_seq OWNED BY "notice"."id"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
model Notice { | ||
id Int @id @default(autoincrement()) | ||
title String | ||
content String | ||
isPopup Boolean @default(false) @map("is_popup") | ||
createdAt DateTime @default(now()) @map("created_at") | ||
deletedAt DateTime? @map("deleted_at") | ||
@@map("notice") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { Notice } from '@prisma/client'; | ||
|
||
export class NoticeDto { | ||
@ApiProperty({ | ||
description: '공지사항 id', | ||
example: 1, | ||
type: Number, | ||
}) | ||
id!: number; | ||
|
||
@ApiProperty({ | ||
description: '공지사항 제목', | ||
example: '공지사항 제목', | ||
type: String, | ||
}) | ||
title!: string; | ||
|
||
@ApiProperty({ | ||
description: '공지사항 내용', | ||
example: '공지사항 내용', | ||
type: String, | ||
}) | ||
content!: string; | ||
|
||
@ApiProperty({ | ||
description: '팝업 공지사항 여부', | ||
example: false, | ||
type: Boolean, | ||
}) | ||
isPopup!: boolean; | ||
|
||
@ApiProperty({ | ||
description: '공지사항 생성 일자', | ||
type: Date, | ||
}) | ||
createdAt!: Date; | ||
|
||
@ApiProperty({ | ||
description: '공지사항 삭제 일자', | ||
type: Date, | ||
}) | ||
deletedAt?: Date; | ||
|
||
static from(notice: Notice): NoticeDto { | ||
return { | ||
id: notice.id, | ||
title: notice.title, | ||
content: notice.content, | ||
isPopup: notice.isPopup, | ||
createdAt: notice.createdAt, | ||
deletedAt: notice.deletedAt, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { | ||
Body, | ||
Controller, | ||
Delete, | ||
Get, | ||
Param, | ||
Post, | ||
Put, | ||
Version, | ||
} from '@nestjs/common'; | ||
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; | ||
import { NoticeDto } from './dto/notice.dto'; | ||
import { NoticeService } from './notice.service'; | ||
import { CreateUpdateNoticePayload } from './payload/create-update-notice.payload'; | ||
|
||
@ApiTags('공지사항 API') | ||
@Controller('notice') | ||
export class NoticeController { | ||
constructor(private readonly noticeService: NoticeService) {} | ||
|
||
@Version('1') | ||
@ApiOkResponse({ type: [NoticeDto] }) | ||
@ApiOperation({ | ||
summary: '공지사항 조회 API', | ||
description: '공지사항을 조회합니다.', | ||
}) | ||
@Get('') | ||
async getNotice(): Promise<NoticeDto[]> { | ||
return this.noticeService.getNotice(); | ||
} | ||
|
||
@Version('1') | ||
@ApiOperation({ | ||
summary: '팝업 공지사항 조회 API', | ||
description: '팝업 공지사항을 조회합니다.', | ||
}) | ||
@Get('popup') | ||
async getPopupNotice(): Promise<NoticeDto> { | ||
return this.noticeService.getPopupNotice(); | ||
} | ||
|
||
@Version('1') | ||
@ApiOperation({ | ||
summary: '팝업 공지사항 등록 API', | ||
description: '팝업 공지사항을 등록합니다.', | ||
}) | ||
@Post('popup/:id') | ||
async createPopupNotice(@Param('id') id: number): Promise<void> { | ||
return this.noticeService.createPopupNotice(id); | ||
} | ||
|
||
@Version('1') | ||
@ApiOperation({ | ||
summary: '공지사항 생성 API', | ||
description: '공지사항을 생성합니다.', | ||
}) | ||
@Post('') | ||
async createNotice( | ||
@Body() payload: CreateUpdateNoticePayload, | ||
): Promise<void> { | ||
return this.noticeService.createNotice(payload); | ||
} | ||
|
||
@Version('1') | ||
@ApiOperation({ | ||
summary: '공지사항 수정 API', | ||
description: '공지사항을 수정합니다.', | ||
}) | ||
@Put(':id') | ||
async updateNotice( | ||
@Param('id') id: number, | ||
@Body() payload: CreateUpdateNoticePayload, | ||
): Promise<void> { | ||
return this.noticeService.updateNotice(id, payload); | ||
} | ||
|
||
@Version('1') | ||
@ApiOperation({ | ||
summary: '공지사항 삭제 API', | ||
description: '공지사항을 삭제합니다.', | ||
}) | ||
@Delete(':id') | ||
async deleteNotice(@Param('id') id: number): Promise<void> { | ||
return this.noticeService.deleteNotice(id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { NoticeController } from './notice.controller'; | ||
import { NoticeRepository } from './notice.repository'; | ||
import { NoticeService } from './notice.service'; | ||
|
||
@Module({ | ||
controllers: [NoticeController], | ||
providers: [NoticeService, NoticeRepository], | ||
}) | ||
export class NoticeModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { PrismaService } from 'src/common/services/prisma.service'; | ||
import { CreateUpdateNoticePayload } from './payload/create-update-notice.payload'; | ||
import { Notice } from './types/notice.type'; | ||
|
||
@Injectable() | ||
export class NoticeRepository { | ||
constructor(private readonly prisma: PrismaService) {} | ||
|
||
async getNotice(): Promise<Notice[]> { | ||
return this.prisma.notice.findMany({ | ||
where: { | ||
deletedAt: null, | ||
}, | ||
orderBy: { | ||
createdAt: 'desc', | ||
}, | ||
}); | ||
} | ||
|
||
async getPopupNotice(): Promise<Notice | null> { | ||
return this.prisma.notice.findFirst({ | ||
where: { | ||
isPopup: true, | ||
deletedAt: null, | ||
}, | ||
orderBy: { | ||
createdAt: 'desc', | ||
}, | ||
}); | ||
} | ||
|
||
async getNoticeById(id: number): Promise<Notice | null> { | ||
return this.prisma.notice.findUnique({ | ||
where: { id, deletedAt: null }, | ||
}); | ||
} | ||
|
||
async createNotice(payload: CreateUpdateNoticePayload): Promise<void> { | ||
await this.prisma.notice.create({ | ||
data: { | ||
title: payload.title, | ||
content: payload.content, | ||
}, | ||
}); | ||
} | ||
|
||
async updateNotice( | ||
id: number, | ||
payload: CreateUpdateNoticePayload, | ||
): Promise<void> { | ||
await this.prisma.notice.update({ | ||
where: { id }, | ||
data: { | ||
title: payload.title, | ||
content: payload.content, | ||
}, | ||
}); | ||
} | ||
|
||
async deleteNotice(id: number): Promise<void> { | ||
await this.prisma.notice.update({ | ||
where: { id }, | ||
data: { deletedAt: new Date() }, | ||
}); | ||
} | ||
|
||
async createPopupNotice(id: number): Promise<void> { | ||
await this.prisma.notice.updateMany({ | ||
where: { isPopup: true }, | ||
data: { isPopup: false }, | ||
}); | ||
|
||
await this.prisma.notice.update({ | ||
where: { id }, | ||
data: { isPopup: true }, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { Injectable, NotFoundException } from '@nestjs/common'; | ||
import { NoticeDto } from './dto/notice.dto'; | ||
import { NoticeRepository } from './notice.repository'; | ||
import { CreateUpdateNoticePayload } from './payload/create-update-notice.payload'; | ||
|
||
@Injectable() | ||
export class NoticeService { | ||
constructor(private readonly noticeRepository: NoticeRepository) {} | ||
|
||
async getNotice(): Promise<NoticeDto[]> { | ||
const notices = await this.noticeRepository.getNotice(); | ||
|
||
return notices.map(NoticeDto.from); | ||
} | ||
|
||
async getPopupNotice(): Promise<NoticeDto> { | ||
const notice = await this.noticeRepository.getPopupNotice(); | ||
|
||
if (!notice) throw new NotFoundException('팝업 공지사항이 없습니다.'); | ||
|
||
return NoticeDto.from(notice); | ||
} | ||
|
||
async createNotice(payload: CreateUpdateNoticePayload): Promise<void> { | ||
return this.noticeRepository.createNotice(payload); | ||
} | ||
|
||
async updateNotice( | ||
id: number, | ||
payload: CreateUpdateNoticePayload, | ||
): Promise<void> { | ||
const notice = await this.noticeRepository.getNoticeById(id); | ||
|
||
if (!notice) throw new NotFoundException('공지사항을 찾을 수 없습니다.'); | ||
|
||
return this.noticeRepository.updateNotice(id, payload); | ||
} | ||
|
||
async deleteNotice(id: number): Promise<void> { | ||
const notice = await this.noticeRepository.getNoticeById(id); | ||
|
||
if (!notice) throw new NotFoundException('공지사항을 찾을 수 없습니다.'); | ||
|
||
return this.noticeRepository.deleteNotice(id); | ||
} | ||
|
||
async createPopupNotice(id: number): Promise<void> { | ||
const notice = await this.noticeRepository.getNoticeById(id); | ||
|
||
if (!notice) throw new NotFoundException('공지사항을 찾을 수 없습니다.'); | ||
|
||
return this.noticeRepository.createPopupNotice(id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { IsString } from 'class-validator'; | ||
|
||
export class CreateUpdateNoticePayload { | ||
@ApiProperty({ | ||
description: '공지사항 제목', | ||
example: '공지사항 제목', | ||
}) | ||
@IsString() | ||
title!: string; | ||
|
||
@ApiProperty({ | ||
description: '공지사항 내용', | ||
example: '공지사항 내용', | ||
}) | ||
@IsString() | ||
content!: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export type Notice = { | ||
id: number; | ||
title: string; | ||
content: string; | ||
isPopup: boolean; | ||
createdAt: Date; | ||
deletedAt: Date | null; | ||
}; |