🎉 Initial commit: Document Server MVP
✨ Features implemented: - FastAPI backend with JWT authentication - PostgreSQL database with async SQLAlchemy - HTML document viewer with smart highlighting - Note system connected to highlights (1:1 relationship) - Bookmark system for quick navigation - Integrated search (documents + notes) - Tag system for document organization - Docker containerization with Nginx 🔧 Technical stack: - Backend: FastAPI + PostgreSQL + Redis - Frontend: Alpine.js + Tailwind CSS - Authentication: JWT tokens - File handling: HTML + PDF support - Search: Full-text search with relevance scoring 📋 Core functionality: - Text selection → Highlight creation - Highlight → Note attachment - Note management with search/filtering - Bookmark creation at scroll positions - Document upload with metadata - User management (admin creates accounts)
This commit is contained in:
47
backend/src/models/highlight.py
Normal file
47
backend/src/models/highlight.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
하이라이트 모델
|
||||
"""
|
||||
from sqlalchemy import Column, String, DateTime, Text, Integer, ForeignKey
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
import uuid
|
||||
|
||||
from src.core.database import Base
|
||||
|
||||
|
||||
class Highlight(Base):
|
||||
"""하이라이트 테이블"""
|
||||
__tablename__ = "highlights"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
|
||||
# 연결 정보
|
||||
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
|
||||
document_id = Column(UUID(as_uuid=True), ForeignKey("documents.id"), nullable=False)
|
||||
|
||||
# 텍스트 위치 정보
|
||||
start_offset = Column(Integer, nullable=False) # 시작 위치
|
||||
end_offset = Column(Integer, nullable=False) # 끝 위치
|
||||
selected_text = Column(Text, nullable=False) # 선택된 텍스트 (검색용)
|
||||
|
||||
# DOM 위치 정보 (정확한 복원을 위해)
|
||||
element_selector = Column(Text, nullable=True) # CSS 선택자
|
||||
start_container_xpath = Column(Text, nullable=True) # 시작 컨테이너 XPath
|
||||
end_container_xpath = Column(Text, nullable=True) # 끝 컨테이너 XPath
|
||||
|
||||
# 스타일 정보
|
||||
highlight_color = Column(String(7), default="#FFFF00") # HEX 색상 코드
|
||||
highlight_type = Column(String(20), default="highlight") # highlight, underline, etc.
|
||||
|
||||
# 메타데이터
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
|
||||
# 관계
|
||||
user = relationship("User", backref="highlights")
|
||||
document = relationship("Document", back_populates="highlights")
|
||||
note = relationship("Note", back_populates="highlight", uselist=False, cascade="all, delete-orphan")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Highlight(id='{self.id}', text='{self.selected_text[:50]}...')>"
|
||||
Reference in New Issue
Block a user