docusort-api / backend /models.py
Mohib
Clean backend API push
8ddf321
Raw
History Blame Contribute Delete
7.72 kB
# File: backend/models.py
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Text, BigInteger
from sqlalchemy.orm import relationship
from datetime import datetime
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=False)
is_frozen = Column(Boolean, default=False)
role = Column(String, default="student")
mfa_enabled = Column(Boolean, default=True)
token_version = Column(Integer, default=1)
otp_code = Column(String, nullable=True)
otp_expiry = Column(DateTime, nullable=True)
ui_theme = Column(String, default="indigo")
font_size = Column(String, default="normal")
auto_sync = Column(Boolean, default=True)
disabled_defaults = Column(String, default="") # <--- NEW: Tracks turned off categories
drives = relationship("ConnectedDrive", back_populates="owner", cascade="all, delete-orphan")
shared_access = relationship("SharedAccess", back_populates="user", cascade="all, delete-orphan")
notifications = relationship("Notification", back_populates="user", cascade="all, delete-orphan")
custom_rules = relationship("CustomRule", back_populates="user", cascade="all, delete-orphan") # <--- NEW
reports_sent = relationship("UserReport", foreign_keys="[UserReport.reporter_id]", back_populates="reporter")
reports_received = relationship("UserReport", foreign_keys="[UserReport.reported_user_id]", back_populates="reported_user")
prompt_templates = relationship("PromptTemplate", back_populates="owner", cascade="all, delete-orphan")
# --- NEW: CUSTOM RULE MODEL ---
class CustomRule(Base):
__tablename__ = "custom_rules"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"))
category_name = Column(String, nullable=False)
keywords = Column(Text, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
user = relationship("User", back_populates="custom_rules")
class ConnectedDrive(Base):
__tablename__ = "connected_drives"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
provider = Column(String)
drive_email = Column(String)
access_token = Column(String)
refresh_token = Column(String)
token_expiry = Column(DateTime)
status = Column(String, default="active")
owner = relationship("User", back_populates="drives")
folders = relationship("IndexedFolder", back_populates="drive", cascade="all, delete-orphan")
class FileMetadata(Base):
__tablename__ = "files"
id = Column(Integer, primary_key=True, index=True)
cloud_id = Column(String, index=True)
name = Column(String)
mime_type = Column(String)
web_view_link = Column(String)
icon_link = Column(String)
category = Column(String, default="Unsorted")
size = Column(BigInteger, nullable=True)
file_hash = Column(String, nullable=True)
cloud_provider = Column(String, default="google")
is_sorted = Column(Boolean, default=False)
is_locked = Column(Boolean, default=False)
original_folder_name = Column(String, nullable=True)
is_ignored_duplicate = Column(Boolean, default=False)
folder_id = Column(Integer, ForeignKey("indexed_folders.id"))
folder = relationship("IndexedFolder", back_populates="files")
course_code = Column(String, default="General")
class IndexedFolder(Base):
__tablename__ = "indexed_folders"
id = Column(Integer, primary_key=True, index=True)
drive_id = Column(Integer, ForeignKey("connected_drives.id"))
folder_id = Column(String)
folder_name = Column(String)
last_synced = Column(DateTime, nullable=True)
is_sorting = Column(Boolean, default=False)
drive = relationship("ConnectedDrive", back_populates="folders")
files = relationship("FileMetadata", back_populates="folder", cascade="all, delete-orphan")
shared_with = relationship("SharedAccess", back_populates="folder", cascade="all, delete-orphan")
share_requests = relationship("ShareRequest", back_populates="folder", cascade="all, delete-orphan")
class ShareRequest(Base):
__tablename__ = "share_requests"
id = Column(Integer, primary_key=True, index=True)
sender_id = Column(Integer, ForeignKey("users.id"))
receiver_email = Column(String, index=True)
folder_id = Column(Integer, ForeignKey("indexed_folders.id"))
status = Column(String, default="pending")
created_at = Column(DateTime, default=datetime.utcnow)
expires_at = Column(DateTime, nullable=True)
sender = relationship("User", foreign_keys=[sender_id])
folder = relationship("IndexedFolder", back_populates="share_requests")
class SharedAccess(Base):
__tablename__ = "shared_access"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
folder_id = Column(Integer, ForeignKey("indexed_folders.id"))
access_level = Column(String, default="view")
expires_at = Column(DateTime, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
user = relationship("User", back_populates="shared_access")
folder = relationship("IndexedFolder", back_populates="shared_with")
class UserReport(Base):
__tablename__ = "user_reports"
id = Column(Integer, primary_key=True, index=True)
type = Column(String, default="report")
reporter_id = Column(Integer, ForeignKey("users.id"), nullable=True)
reporter_email_fallback = Column(String, nullable=True)
reported_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
reason = Column(String)
description = Column(Text, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
status = Column(String, default="open")
admin_response = Column(Text, nullable=True)
reporter = relationship("User", foreign_keys=[reporter_id], back_populates="reports_sent")
reported_user = relationship("User", foreign_keys=[reported_user_id], back_populates="reports_received")
class Notification(Base):
__tablename__ = "notifications"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
message = Column(Text)
is_read = Column(Boolean, default=False)
created_at = Column(DateTime, default=datetime.utcnow)
user = relationship("User", back_populates="notifications")
class UserLog(Base):
__tablename__ = "user_logs"
id = Column(Integer, primary_key=True, index=True)
user_email = Column(String, index=True)
action = Column(String)
details = Column(Text)
timestamp = Column(DateTime, default=datetime.utcnow)
undo_payload = Column(Text)
class BlacklistedEmail(Base):
__tablename__ = "blacklisted_emails"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
reason = Column(String)
banned_by = Column(String)
banned_at = Column(DateTime, default=datetime.utcnow)
class PromptTemplate(Base):
__tablename__ = "prompt_templates"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"))
name = Column(String, nullable=False)
prompt_text = Column(Text, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
owner = relationship("User", back_populates="prompt_templates")