diff --git a/backend/src/api/routes/documents.py b/backend/src/api/routes/documents.py index d43c4d0..103a6e1 100644 --- a/backend/src/api/routes/documents.py +++ b/backend/src/api/routes/documents.py @@ -83,12 +83,13 @@ router = APIRouter() @router.get("/", response_model=List[DocumentResponse]) async def list_documents( skip: int = 0, - limit: int = 50, + limit: int = 50, # 기본값 복원 tag: Optional[str] = None, search: Optional[str] = None, current_user: User = Depends(get_current_active_user), db: AsyncSession = Depends(get_db) ): + """페이지네이션이 있는 문서 목록 조회""" """문서 목록 조회""" query = select(Document).options( selectinload(Document.uploader), @@ -160,6 +161,70 @@ async def list_documents( return response_data +@router.get("/all", response_model=List[DocumentResponse]) +async def list_all_documents( + current_user: User = Depends(get_current_active_user), + db: AsyncSession = Depends(get_db) +): + """모든 문서 조회 (페이지네이션 없음) - 프론트엔드 전용""" + + query = select(Document).options( + selectinload(Document.uploader), + selectinload(Document.tags), + selectinload(Document.book), # 서적 정보 추가 + selectinload(Document.category) # 소분류 정보 추가 + ) + + # 권한 필터링 (관리자가 아니면 공개 문서 + 자신이 업로드한 문서만) + if not current_user.is_admin: + query = query.where( + or_( + Document.is_public == True, + Document.uploaded_by == current_user.id + ) + ) + + query = query.order_by(Document.created_at.desc()) + + result = await db.execute(query) + documents = result.scalars().all() + + # 응답 데이터 변환 + response_data = [] + for doc in documents: + doc_data = DocumentResponse( + id=str(doc.id), + title=doc.title, + description=doc.description, + html_path=doc.html_path, # None 가능 (PDF만 업로드한 경우) + pdf_path=doc.pdf_path, + thumbnail_path=doc.thumbnail_path, + file_size=doc.file_size, + page_count=doc.page_count, + language=doc.language, + is_public=doc.is_public, + is_processed=doc.is_processed, + created_at=doc.created_at, + updated_at=doc.updated_at, + document_date=doc.document_date, + uploader_name=doc.uploader.full_name or doc.uploader.email, + tags=[tag.name for tag in doc.tags], + # 서적 정보 추가 + book_id=str(doc.book.id) if doc.book else None, + book_title=doc.book.title if doc.book else None, + book_author=doc.book.author if doc.book else None, + # 소분류 정보 추가 + category_id=str(doc.category.id) if doc.category else None, + category_name=doc.category.name if doc.category else None, + sort_order=doc.sort_order, + # PDF 매칭 정보 추가 + matched_pdf_id=str(doc.matched_pdf_id) if doc.matched_pdf_id else None + ) + response_data.append(doc_data) + + return response_data + + @router.get("/hierarchy/structured", response_model=dict) async def get_documents_by_hierarchy( current_user: User = Depends(get_current_active_user), @@ -375,10 +440,14 @@ async def upload_document( await db.commit() - # 문서 정보를 다시 로드 (태그 포함) + # 문서 정보를 다시 로드 (태그, 서적, 카테고리 포함) result = await db.execute( select(Document) - .options(selectinload(Document.tags)) + .options( + selectinload(Document.tags), + selectinload(Document.book), + selectinload(Document.category) + ) .where(Document.id == document.id) ) document_with_tags = result.scalar_one() @@ -401,6 +470,14 @@ async def upload_document( document_date=document_with_tags.document_date, uploader_name=current_user.full_name or current_user.email, tags=[tag.name for tag in document_with_tags.tags], + # 서적 정보 추가 + book_id=str(document_with_tags.book.id) if document_with_tags.book else None, + book_title=document_with_tags.book.title if document_with_tags.book else None, + book_author=document_with_tags.book.author if document_with_tags.book else None, + # 소분류 정보 추가 + category_id=str(document_with_tags.category.id) if document_with_tags.category else None, + category_name=document_with_tags.category.name if document_with_tags.category else None, + sort_order=document_with_tags.sort_order, matched_pdf_id=str(document_with_tags.matched_pdf_id) if document_with_tags.matched_pdf_id else None ) diff --git a/frontend/book-editor.html b/frontend/book-editor.html index 6a86ed6..f297e6f 100644 --- a/frontend/book-editor.html +++ b/frontend/book-editor.html @@ -95,16 +95,29 @@ rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"> + + +
+ + + +
- +

- - 문서 순서 및 PDF 매칭 + + HTML 문서 순서 및 PDF 매칭

- -
+ +