Files
frontend/docs/bbs/post-archi.md
T

481 lines
18 KiB
Markdown

# 게시물(Post) 관리 프로그램 아키텍처 문서
## 개요
이 문서는 게시물(Post) 관리 프로그램의 아키텍처와 소스 흐름에 대한 상세 설명입니다. 게시물 관리 기능은 게시판에 게시물을 등록, 조회, 수정, 삭제하는 기능을 제공하며, 다양한 유형의 게시물(일반, 이미지, 동영상, 공지사항 등)을 지원합니다.
## 기술 스택
- **프레임워크**: Next.js (App Router)
- **상태 관리**: React Query, Zustand(useMenuStore, useUserStore)
- **UI 컴포넌트**: @common/components
- **테이블 관리**: TanStack Table
- **폼 관리**: React Hook Form, Zod
- **API 통신**: Axios
- **파일 업로드**: 커스텀 파일 업로더 컴포넌트
## 디렉토리 구조
```
frontend/
├── apps/
│ └── cs/
│ ├── app/
│ │ └── (with-base-layout)/
│ │ └── bbs/
│ │ └── (post)/ # 게시물 관련 페이지
│ ├── src/
│ │ ├── entities/
│ │ │ ├── post/
│ │ │ │ ├── api/
│ │ │ │ │ └── post-service.ts # 게시물 API 호출 함수
│ │ │ │ └── model/
│ │ │ │ └── post-interface.ts # 게시물 인터페이스 정의
│ │ │ └── posting/
│ │ │ ├── api/
│ │ │ │ └── posting-service.ts # 게시 관련 API 호출 함수
│ │ │ ├── model/
│ │ │ │ └── posting-interface.ts # 게시 관련 인터페이스 정의
│ │ │ └── ui/
│ │ │ └── posting-dialog.tsx # 게시 관련 다이얼로그 컴포넌트
│ │ ├── pages/
│ │ │ └── (post)/
│ │ │ ├── image/
│ │ │ │ └── ui/
│ │ │ │ └── image-post.tsx # 이미지 게시물 컴포넌트
│ │ │ ├── movie/
│ │ │ │ └── ui/
│ │ │ │ └── movie-post.tsx # 동영상 게시물 컴포넌트
│ │ │ ├── normal/
│ │ │ │ └── ui/
│ │ │ │ └── normal-post.tsx # 일반 게시물 컴포넌트
│ │ │ └── notice/
│ │ │ └── ui/
│ │ │ └── notice-post.tsx # 공지사항 게시물 컴포넌트
│ │ └── widgets/
│ │ └── post/
│ │ ├── model/
│ │ │ ├── post-table-columns.tsx # 게시물 테이블 컬럼 정의
│ │ │ └── grid-view-table-columns.tsx # 그리드 뷰 테이블 컬럼 정의
│ │ └── ui/
│ │ ├── post-action.tsx # 게시물 액션 컴포넌트
│ │ ├── post-comment.tsx # 게시물 댓글 컴포넌트
│ │ ├── post-form.tsx # 게시물 등록/수정 폼
│ │ ├── post-page.tsx # 게시물 목록 페이지
│ │ ├── post.tsx # 게시물 상세 컴포넌트
│ │ └── posting-period-selector.tsx # 게시 기간 선택기
```
## 데이터 모델
### 게시물(Post) 인터페이스
```typescript
export interface Post {
rowNo: number; // 행 번호
bbsId: number; // 게시판 ID
pstNo: number; // 게시물 번호
pstTtl: string; // 게시물 제목
pstCn: string; // 게시물 내용
inqNocs: number; // 조회수
rfrncUrl: string; // 참조 URL
popupYn: string; // 팝업 여부
upndFixYn: string; // 상단 고정 여부
prdPstgYn: string; // 기간 게시 여부
rootPath: string; // 루트 경로
pstPath: string; // 게시물 경로
ansPstn: number; // 답변 위치
wrtrNm: string; // 작성자명
wrtrCplc: string; // 작성자 소속
atflCd: string; // 첨부파일 코드
regDt: string; // 등록일시
rgtrNm: string; // 등록자명
cmntCnt: number; // 댓글 수
}
```
### 게시물 상세 정보(PostInfo) 인터페이스
```typescript
export interface PostInfo extends Post {
pstCn: string; // 게시물 내용
rgtr: string; // 등록자
mdfcnDt: string; // 수정일시
mdfr: string; // 수정자
}
```
### 최근 게시물(RecentPost) 인터페이스
```typescript
export interface RecentPost extends Post {
bbsNm: string; // 게시판명
bbsTypeCd: string; // 게시판 유형 코드
}
```
### 게시물 이동(MovePost) 인터페이스
```typescript
export interface MovePost {
fromBbsId: number; // 출발 게시판 ID
toBbsId?: number; // 도착 게시판 ID
pstNo: number; // 게시물 번호
}
```
### 게시물 삭제(DeletePost) 인터페이스
```typescript
export interface DeletePost {
bbsId: number; // 게시판 ID
pstNo: number; // 게시물 번호
delRsn?: string; // 삭제 사유
}
```
### 게시물 검색 파라미터(PostParams) 인터페이스
```typescript
export interface PostParams extends PageableParams {
keywordType?: string; // 검색 키워드 유형 (제목, 내용, 작성자 등)
keyword?: string; // 검색 키워드
popupYn?: string; // 팝업 여부
upndFixYn?: string; // 상단 고정 여부
prdPstgYn?: string; // 기간 게시 여부
siteId?: string; // 사이트 ID
bbsTypeCd?: string; // 게시판 유형 코드
}
```
### 최근 게시물 검색 파라미터(RecentPostParams) 인터페이스
```typescript
export interface RecentPostParams extends PageableParams {
keywordType?: string; // 검색 키워드 유형
keyword?: string; // 검색 키워드
bbsId?: number | null; // 게시판 ID
delYn?: string; // 삭제 여부
frDateYmd?: string; // 시작 날짜
toDateYmd?: string; // 종료 날짜
}
```
### 게시물 폼 데이터(PostFormData) 인터페이스
Zod 스키마를 사용하여 폼 데이터의 유효성 검증을 수행합니다.
```typescript
export const postFormSchema = z.object({
bbsId: z.number(), // 게시판 ID
pstTtl: z.string().nonempty(), // 게시물 제목
pstCn: z.string().nullish(), // 게시물 내용
rfrncUrl: z.string().nullish(), // 참조 URL
popupYn: z.string().nullish(), // 팝업 여부
popupYnEtc: z.array(postEtcSchema).nullish(), // 팝업 관련 추가 정보
upndFixYn: z.string().nullish(), // 상단 고정 여부
upndFixYnEtc: z.array(postEtcSchema).nullish(), // 상단 고정 관련 추가 정보
prdPstgYn: z.string().nullish(), // 기간 게시 여부
prdPstgYnEtc: z.array(postEtcSchema).nullish(), // 기간 게시 관련 추가 정보
pstPswd: z.string(), // 게시물 비밀번호
wrtrNm: z.string().nullish(), // 작성자명
wrtrCplc: z.string().nullish(), // 작성자 소속
atflCd: z.string().nullish(), // 첨부파일 코드
parentPstNo: z.number().nullish(), // 부모 게시물 번호
});
```
## API 기능
게시물 관리 API는 다음과 같은 기능을 제공합니다:
### 1. 게시물 목록 조회
```typescript
getPostList: async (bbsId: number, params: PostParams): Promise<PostList> => {
const response = await client.get<PostList>(
`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}`,
{ params },
);
return response.data;
}
```
- **설명**: 특정 게시판의 게시물 목록을 페이지네이션과 함께 조회합니다.
- **파라미터**: `bbsId` (게시판 ID), `PostParams` (검색 조건)
- **반환값**: 페이지네이션된 게시물 목록 (`PostList`)
### 2. 최근 게시물 목록 조회
```typescript
getRecentPostList: async (params?: RecentPostParams): Promise<RecentPostList> => {
const response = await client.get<RecentPostList>(
`${ENDPOINT.BOARD_SERVICE.POSTS}/recentPosts`,
{ params },
);
return response.data;
}
```
- **설명**: 최근 게시물 목록을 조회합니다.
- **파라미터**: `RecentPostParams` (검색 조건)
- **반환값**: 페이지네이션된 최근 게시물 목록 (`RecentPostList`)
### 3. 게시물 상세 조회
```typescript
getPostInfo: async (bbsId: number, pstNo: number): Promise<PostInfo> => {
const response = await client.get<PostInfo>(
`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`,
);
return response.data;
}
```
- **설명**: 특정 게시물의 상세 정보를 조회합니다.
- **파라미터**: `bbsId` (게시판 ID), `pstNo` (게시물 번호)
- **반환값**: 게시물 상세 정보 (`PostInfo`)
### 4. 게시물 생성
```typescript
createPost: async (data: PostFormData): Promise<Post> => {
const validatedData = postFormSchema.parse(data);
const response = await client.post<Post>(
`${ENDPOINT.BOARD_SERVICE.POSTS}`,
validatedData,
);
return response.data;
}
```
- **설명**: 새로운 게시물을 생성합니다.
- **파라미터**: `PostFormData` (게시물 생성 데이터)
- **반환값**: 생성된 게시물 정보 (`Post`)
### 5. 게시물 수정
```typescript
updatePost: async (bbsId: number, pstNo: number, data: PostUpdateFormData): Promise<Post> => {
const validatedData = postUpdateFormSchema.parse(data);
const response = await client.put<Post>(
`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`,
validatedData,
);
return response.data;
}
```
- **설명**: 기존 게시물 정보를 수정합니다.
- **파라미터**: `bbsId` (게시판 ID), `pstNo` (게시물 번호), `PostUpdateFormData` (수정할 게시물 데이터)
- **반환값**: 수정된 게시물 정보 (`Post`)
### 6. 게시물 삭제
```typescript
deletePost: async (bbsId: number, pstNo: number, delRsn?: string): Promise<void> => {
await client.delete(`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`, {
params: { delRsn },
});
}
```
- **설명**: 게시물을 삭제합니다.
- **파라미터**: `bbsId` (게시판 ID), `pstNo` (게시물 번호), `delRsn` (삭제 사유, 선택적)
- **반환값**: void
### 7. 게시물 소프트 삭제 (여러 게시물)
```typescript
softDeletePost: async (data: DeletePost[]): Promise<void> => {
await client.post(`${ENDPOINT.BOARD_SERVICE.POSTS}/softDeleteSels`, data);
}
```
- **설명**: 여러 게시물을 소프트 삭제합니다 (실제 삭제하지 않고 삭제 표시만 함).
- **파라미터**: `DeletePost[]` (삭제할 게시물 목록)
- **반환값**: void
### 8. 게시물 하드 삭제 (여러 게시물)
```typescript
hardDeletePost: async (data: DeletePost[]): Promise<void> => {
await client.post(`${ENDPOINT.BOARD_SERVICE.POSTS}/hardDeleteSels`, data);
}
```
- **설명**: 여러 게시물을 하드 삭제합니다 (실제로 데이터베이스에서 삭제).
- **파라미터**: `DeletePost[]` (삭제할 게시물 목록)
- **반환값**: void
### 9. 게시물 이동
```typescript
movePost: async (data: MovePost[]): Promise<void> => {
await client.post(`${ENDPOINT.BOARD_SERVICE.POSTS}/movePstByBbsId`, data);
}
```
- **설명**: 게시물을 다른 게시판으로 이동합니다.
- **파라미터**: `MovePost[]` (이동할 게시물 정보 목록)
- **반환값**: void
### 10. 게시물 복구
```typescript
restorePost: async (data: DeletePost[]): Promise<void> => {
await client.post(`${ENDPOINT.BOARD_SERVICE.POSTS}/restoreSels`, data);
}
```
- **설명**: 소프트 삭제된 게시물을 복구합니다.
- **파라미터**: `DeletePost[]` (복구할 게시물 목록)
- **반환값**: void
## 프로그램 흐름
### 1. 게시물 목록 조회 흐름
1. 사용자가 게시판 페이지에 접근
2. `useMenuStore`를 통해 현재 게시판 정보 로드
3. React Query를 사용하여 `getPostList` API 호출
4. 상단 고정 게시물이 있는 경우 별도로 조회하여 목록 상단에 표시
5. 검색 조건 변경 시 쿼리 파라미터 업데이트 및 API 재호출
6. 응답 데이터를 TanStack Table을 사용하여 테이블 형태로 표시
7. 게시판 유형에 따라 일반 테이블 또는 그리드 뷰로 표시
### 2. 게시물 상세 조회 흐름
1. 사용자가 게시물 목록에서 특정 게시물 클릭
2. 해당 게시물의 상세 페이지로 이동 (`/bbs/{bbsId}/{pstNo}`)
3. React Query를 사용하여 `getPostInfo` API 호출
4. 게시물 상세 정보 및 첨부파일 정보 로드
5. 게시판 유형에 따라 적절한 상세 보기 컴포넌트 렌더링
- 일반 게시물: `normal-post.tsx`
- 이미지 게시물: `image-post.tsx`
- 동영상 게시물: `movie-post.tsx`
- 공지사항: `notice-post.tsx`
### 3. 게시물 등록 흐름
1. 사용자가 게시물 등록 버튼 클릭
2. 게시물 등록 페이지로 이동 (`/bbs/{bbsId}/register`)
3. React Hook Form과 Zod를 사용하여 폼 데이터 관리 및 유효성 검증
4. 첨부파일 업로드 시 `AttachmentApi`를 통해 파일 업로드 및 `atflCd` 획득
5. 저장 버튼 클릭 시 확인 다이얼로그 표시 후 `createPost` API 호출
6. 성공 시 게시물 목록 페이지로 리다이렉트
### 4. 게시물 수정 흐름
1. 사용자가 게시물 상세 페이지에서 수정 버튼 클릭
2. 게시물 수정 페이지로 이동 (`/bbs/{bbsId}/{pstNo}/modify`)
3. `getPostInfo` API를 호출하여 기존 게시물 데이터 로드
4. 기존 첨부파일 정보 로드 및 표시
5. 사용자가 데이터 수정 후 저장 버튼 클릭
6. 확인 다이얼로그 표시 후 `updatePost` API 호출
7. 성공 시 게시물 상세 페이지로 리다이렉트
### 5. 게시물 삭제 흐름
1. 사용자가 게시물 상세 페이지에서 삭제 버튼 클릭 또는 목록에서 여러 게시물 선택 후 삭제 버튼 클릭
2. 삭제 사유 입력 다이얼로그 표시
3. 사용자가 삭제 사유 입력 후 확인
4. 단일 게시물 삭제 시 `deletePost` API 호출, 여러 게시물 삭제 시 `softDeletePost` 또는 `hardDeletePost` API 호출
5. 성공 시 게시물 목록 페이지로 리다이렉트 또는 목록 새로고침
## 주요 컴포넌트
### 1. PostPage 컴포넌트
게시물 목록을 조회하고 표시하는 페이지 컴포넌트입니다.
- **기능**:
- 게시물 검색 (제목, 내용, 작성자 등)
- 페이지네이션
- 페이지 크기 조정
- 게시물 목록 표시 (테이블 또는 그리드 뷰)
- 게시물 등록 페이지로 이동
- 게시물 상세 페이지로 이동 (행 클릭)
- 선택한 게시물 삭제
### 2. PostForm 컴포넌트
게시물 등록 및 수정에 사용되는 폼 컴포넌트입니다.
- **기능**:
- 게시물 정보 입력/수정 (제목, 내용, 작성자 등)
- 첨부파일 업로드 및 관리
- 참조 URL 입력 (게시판 설정에 따라)
- 팝업 게시 설정 (게시판 설정에 따라)
- 상단 고정 설정 (게시판 설정에 따라)
- 기간 게시 설정 (게시판 설정에 따라)
- 저장 확인 다이얼로그
- 취소 기능
### 3. Post 컴포넌트
게시물 상세 정보를 표시하는 컴포넌트입니다.
- **기능**:
- 게시물 상세 정보 표시
- 첨부파일 다운로드
- 수정/삭제 버튼
- 목록으로 돌아가기
- 댓글 표시 및 관리 (게시판 설정에 따라)
### 4. PostComment 컴포넌트
게시물 댓글을 표시하고 관리하는 컴포넌트입니다.
- **기능**:
- 댓글 목록 표시
- 댓글 등록
- 댓글 수정/삭제
- 댓글 페이지네이션
### 5. PostingPeriodSelector 컴포넌트
게시 기간을 선택하는 컴포넌트입니다.
- **기능**:
- 게시 기간 유형 선택
- 시작일/종료일 선택
- 게시 기간 설정
### 6. 게시물 유형별 컴포넌트
게시판 유형에 따라 다양한 게시물 컴포넌트를 제공합니다.
- **NormalPost**: 일반 텍스트 게시물 컴포넌트
- **ImagePost**: 이미지 게시물 컴포넌트 (이미지 갤러리 형태)
- **MoviePost**: 동영상 게시물 컴포넌트 (동영상 플레이어 포함)
- **NoticePost**: 공지사항 게시물 컴포넌트
## 아키텍처 특징
1. **계층 분리**: API, 모델, UI 컴포넌트가 명확히 분리되어 있습니다.
2. **타입 안전성**: TypeScript 인터페이스와 Zod 스키마를 통한 타입 검증을 제공합니다.
3. **컴포넌트 재사용**: 공통 컴포넌트를 활용하여 코드 중복을 최소화합니다.
4. **유효성 검증**: Zod 스키마를 사용하여 폼 데이터의 유효성을 검증합니다.
5. **상태 관리**: React Query를 통한 서버 상태 관리와 Zustand를 통한 클라이언트 상태 관리를 제공합니다.
6. **조건부 렌더링**: 게시판 설정에 따라 UI 요소를 조건부로 렌더링합니다.
7. **다양한 게시물 유형 지원**: 일반, 이미지, 동영상, 공지사항 등 다양한 게시물 유형을 지원합니다.
## 확장 가능성
1. **다국어 지원**: 게시물 내용의 다국어 지원 기능 추가
2. **게시물 버전 관리**: 게시물 수정 이력 관리 기능 추가
3. **게시물 예약 발행**: 특정 시간에 자동으로 게시되는 기능 추가
4. **게시물 통계**: 조회수, 좋아요 등 게시물 통계 기능 강화
5. **게시물 공유**: 소셜 미디어 공유 기능 추가
6. **게시물 알림**: 새 게시물 알림 기능 추가
7. **게시물 태그**: 게시물 태그 및 카테고리 기능 추가
## 주의사항
1. 게시물 삭제 시 연관된 첨부파일, 댓글 등의 처리에 주의가 필요합니다.
2. 게시물 이동 시 게시판 유형 간 호환성 문제가 발생할 수 있습니다.
3. 첨부파일 업로드 시 파일 크기 및 유형 제한을 준수해야 합니다.
4. 게시 기간 설정 시 시간대(timezone) 처리에 주의가 필요합니다.
5. 비로그인 사용자의 게시물 작성 시 비밀번호 관리에 주의가 필요합니다.