feat: Add bulletin board system
- Add BoardCategory and BoardPost models with multi-language support - Add bulletin API endpoints (CRUD, notice toggle, pin toggle) - Add board_enabled setting to control menu visibility - Create frontend board pages (list, detail, write, edit) - Create admin board management and category management pages - Update Header.tsx with conditional Board menu between Inquiry and Contact Us - Update admin settings with board_enabled toggle - Add Board menu to admin sidebar Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
125
backend/app/schemas/bulletin.py
Normal file
125
backend/app/schemas/bulletin.py
Normal file
@@ -0,0 +1,125 @@
|
||||
"""
|
||||
Bulletin Board Schemas - 게시판 스키마
|
||||
"""
|
||||
from datetime import datetime
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
# ============ Category Schemas ============
|
||||
|
||||
class BoardCategoryBase(BaseModel):
|
||||
name: str
|
||||
name_en: Optional[str] = None
|
||||
name_mn: Optional[str] = None
|
||||
name_ru: Optional[str] = None
|
||||
slug: str
|
||||
description: Optional[str] = None
|
||||
sort_order: int = 0
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class BoardCategoryCreate(BoardCategoryBase):
|
||||
pass
|
||||
|
||||
|
||||
class BoardCategoryUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
name_en: Optional[str] = None
|
||||
name_mn: Optional[str] = None
|
||||
name_ru: Optional[str] = None
|
||||
slug: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
sort_order: Optional[int] = None
|
||||
is_active: Optional[bool] = None
|
||||
|
||||
|
||||
class BoardCategoryResponse(BoardCategoryBase):
|
||||
id: int
|
||||
created_at: datetime
|
||||
updated_at: Optional[datetime] = None
|
||||
post_count: int = 0
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ============ Post Schemas ============
|
||||
|
||||
class BoardPostBase(BaseModel):
|
||||
title: str
|
||||
content: str
|
||||
category_id: int
|
||||
|
||||
|
||||
class BoardPostCreate(BoardPostBase):
|
||||
is_notice: bool = False # 관리자만 true 가능
|
||||
|
||||
|
||||
class BoardPostUpdate(BaseModel):
|
||||
title: Optional[str] = None
|
||||
content: Optional[str] = None
|
||||
category_id: Optional[int] = None
|
||||
is_notice: Optional[bool] = None
|
||||
is_pinned: Optional[bool] = None
|
||||
is_published: Optional[bool] = None
|
||||
|
||||
|
||||
class AuthorResponse(BaseModel):
|
||||
id: int
|
||||
name: Optional[str] = None
|
||||
email: str
|
||||
is_admin: bool = False
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BoardPostResponse(BaseModel):
|
||||
id: int
|
||||
title: str
|
||||
content: str
|
||||
category_id: int
|
||||
category: Optional[BoardCategoryResponse] = None
|
||||
author_id: int
|
||||
author: Optional[AuthorResponse] = None
|
||||
is_notice: bool
|
||||
is_pinned: bool
|
||||
is_published: bool
|
||||
view_count: int
|
||||
created_at: datetime
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BoardPostListItem(BaseModel):
|
||||
"""목록에서 보여줄 간략한 정보"""
|
||||
id: int
|
||||
title: str
|
||||
category_id: int
|
||||
category_name: Optional[str] = None
|
||||
author_id: int
|
||||
author_name: Optional[str] = None
|
||||
is_notice: bool
|
||||
is_pinned: bool
|
||||
view_count: int
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class BoardPostListResponse(BaseModel):
|
||||
posts: List[BoardPostListItem]
|
||||
notices: List[BoardPostListItem] # 공지사항 (상단 고정)
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
total_pages: int
|
||||
|
||||
|
||||
class BoardCategoryListResponse(BaseModel):
|
||||
categories: List[BoardCategoryResponse]
|
||||
total: int
|
||||
Reference in New Issue
Block a user