mirror of
https://git.victorphan.net/basketballcantho/ten-project.git
synced 2026-08-05 11:53:10 +07:00
hoàn thành phần Authentication
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Integer,
|
||||
String,
|
||||
Text,
|
||||
ForeignKey,
|
||||
DateTime,
|
||||
UniqueConstraint,
|
||||
)
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import relationship
|
||||
from .database import Base
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
username = Column(String(64), unique=True, nullable=False, index=True)
|
||||
email = Column(String(255), unique=True, nullable=False, index=True)
|
||||
password_hash = Column(String(255), nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
|
||||
# Relationships
|
||||
pdfs = relationship("PDF", back_populates="owner", cascade="all, delete-orphan")
|
||||
annotations = relationship("Annotation", back_populates="owner", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class PDF(Base):
|
||||
__tablename__ = "pdfs"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
|
||||
title = Column(String(255), nullable=False)
|
||||
file_path = Column(Text, nullable=False) # path inside Docker volume
|
||||
total_pages = Column(Integer, nullable=True) # populated after upload processing
|
||||
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
||||
|
||||
# Relationships
|
||||
owner = relationship("User", back_populates="pdfs")
|
||||
annotations = relationship("Annotation", back_populates="pdf", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Annotation(Base):
|
||||
__tablename__ = "annotations"
|
||||
__table_args__ = (
|
||||
# One annotation record per (pdf, user, page) — upsert target
|
||||
UniqueConstraint("pdf_id", "user_id", "page_number", name="uq_annotation_pdf_user_page"),
|
||||
)
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
pdf_id = Column(Integer, ForeignKey("pdfs.id", ondelete="CASCADE"), nullable=False, index=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
|
||||
page_number = Column(Integer, nullable=False) # 1-based
|
||||
canvas_data = Column(JSONB, nullable=False, default=dict) # Fabric.js JSON state
|
||||
updated_at = Column(
|
||||
DateTime(timezone=True),
|
||||
default=lambda: datetime.now(timezone.utc),
|
||||
onupdate=lambda: datetime.now(timezone.utc),
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
# Relationships
|
||||
pdf = relationship("PDF", back_populates="annotations")
|
||||
owner = relationship("User", back_populates="annotations")
|
||||
Reference in New Issue
Block a user