feat: 계층구조 뷰 및 완전한 하이라이트/메모 시스템 구현

주요 기능:
- 📚 Book 및 BookCategory 모델 추가 (서적 그룹화)
- 🏗️ 계층구조 뷰 (Book > Category > Document) 구현
- 🎨 완전한 하이라이트 시스템 (생성, 표시, 삭제)
- 📝 통합 메모 관리 (추가, 수정, 삭제)
- 🔄 그리드 뷰와 계층구조 뷰 간 완전 동기화
- 🛡️ 관리자 전용 문서 삭제 기능
- 🔧 모든 CORS 및 500 오류 해결

기술적 개선:
- API 베이스 URL을 Nginx 프록시로 변경 (/api)
- 외래키 제약 조건 해결 (삭제 순서 최적화)
- SQLAlchemy 관계 로딩 최적화 (selectinload)
- 프론트엔드 캐시 무효화 시스템
- Alpine.js 컴포넌트 구조 개선

UI/UX:
- 계층구조 네비게이션 (사이드바 + 트리 구조)
- 하이라이트 모드 토글 스위치
- 완전한 툴팁 기반 메모 관리 인터페이스
- 반응형 하이라이트 메뉴 (색상 선택)
- 스마트 툴팁 위치 조정 (화면 경계 고려)
This commit is contained in:
Hyungi Ahn
2025-08-23 14:31:30 +09:00
parent 1e2e66d8fe
commit 46546da55f
18 changed files with 3206 additions and 384 deletions

View File

@@ -0,0 +1,32 @@
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from uuid import UUID
class BookBase(BaseModel):
title: str = Field(..., min_length=1, max_length=500)
author: Optional[str] = Field(None, max_length=255)
description: Optional[str] = None
language: str = Field("ko", max_length=10)
is_public: bool = False
class CreateBookRequest(BookBase):
pass
class UpdateBookRequest(BookBase):
pass
class BookResponse(BookBase):
id: UUID
created_at: datetime
updated_at: Optional[datetime]
document_count: int = 0 # 문서 개수 추가
class Config:
from_attributes = True
class BookSearchResponse(BookResponse):
pass
class BookSuggestionResponse(BookResponse):
similarity_score: float = Field(..., ge=0.0, le=1.0)

View File

@@ -0,0 +1,31 @@
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from uuid import UUID
class BookCategoryBase(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
description: Optional[str] = None
sort_order: int = Field(0, ge=0)
class CreateBookCategoryRequest(BookCategoryBase):
book_id: UUID
class UpdateBookCategoryRequest(BaseModel):
name: Optional[str] = Field(None, min_length=1, max_length=200)
description: Optional[str] = None
sort_order: Optional[int] = Field(None, ge=0)
class BookCategoryResponse(BookCategoryBase):
id: UUID
book_id: UUID
created_at: datetime
updated_at: Optional[datetime]
document_count: int = 0 # 포함된 문서 수
class Config:
from_attributes = True
class UpdateDocumentOrderRequest(BaseModel):
document_orders: List[dict] = Field(..., description="문서 ID와 순서 정보")
# 예: [{"document_id": "uuid", "sort_order": 1}, ...]