File size: 7,724 Bytes
8ddf321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# 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")