# File: backend/schemas.py from pydantic import BaseModel, EmailStr from typing import Optional, List from datetime import datetime class UserBase(BaseModel): email: EmailStr class UserCreate(UserBase): password: str class UserResponse(UserBase): id: int email: str is_active: bool is_frozen: bool role: str mfa_enabled: bool ui_theme: str font_size: str auto_sync: bool disabled_defaults: Optional[str] = "" # <--- NEW class Config: from_attributes = True class UserSettingsUpdate(BaseModel): mfa_enabled: bool ui_theme: str font_size: str auto_sync: bool disabled_defaults: str # <--- NEW # --- NEW: CUSTOM RULES SCHEMAS --- class CustomRuleBase(BaseModel): category_name: str keywords: str class CustomRuleResponse(CustomRuleBase): id: int class Config: from_attributes = True class VerifyOTPRequest(BaseModel): email: EmailStr otp: str class Token(BaseModel): access_token: str token_type: str class FolderSelectRequest(BaseModel): folder_id: str folder_name: str class IndexedFolderResponse(BaseModel): id: int drive_id: int folder_id: str folder_name: str is_sorting: bool # Define the fields total_files: int = 0 sorted_files: int = 0 class Config: from_attributes = True # This replaces the deprecated 'orm_mode' # Use a model_validator to calculate the fields from the ORM object @classmethod def model_validate(cls, obj, *args, **kwargs): # Let Pydantic perform the base validation instance = super().model_validate(obj, *args, **kwargs) # Manually inject the counts from the SQLAlchemy relationship if hasattr(obj, 'files'): instance.total_files = len(obj.files) instance.sorted_files = sum(1 for f in obj.files if getattr(f, 'is_sorted', False)) return instance class ShareRequestCreate(BaseModel): receiver_email: EmailStr folder_id: int expires_in_days: Optional[int] = None class ShareRequestResponse(BaseModel): id: int sender_email: str folder_name: str status: str created_at: datetime expires_at: Optional[datetime] class Config: from_attributes = True class RespondToShare(BaseModel): request_id: int accept: bool class SharedUserResponse(BaseModel): access_id: int user_email: str access_level: str expires_at: Optional[datetime] class ReportCreate(BaseModel): reported_email: EmailStr reason: str description: Optional[str] = None class AppealCreate(BaseModel): email: EmailStr reason: str description: str class ReportResponse(BaseModel): id: int type: str reporter_email: Optional[str] reported_user_email: Optional[str] reason: str description: Optional[str] status: str admin_response: Optional[str] created_at: datetime class Config: from_attributes = True class ResolveReportRequest(BaseModel): response: str class ForgotPasswordRequest(BaseModel): email: EmailStr class ResetPasswordRequest(BaseModel): email: EmailStr otp: str new_password: str class AdminUserDetail(BaseModel): user: UserResponse drives: List[dict] class LogResponse(BaseModel): id: int user_email: str action: str details: str timestamp: datetime undo_payload: Optional[str] = None class Config: from_attributes = True class BanRequest(BaseModel): email: EmailStr reason: str class NotificationResponse(BaseModel): id: int message: str is_read: bool created_at: datetime class Config: from_attributes = True class BlacklistResponse(BaseModel): id: int email: str reason: str banned_by: str banned_at: datetime class Config: from_attributes = True class PromptTemplateBase(BaseModel): name: str prompt_text: str class PromptTemplateCreate(PromptTemplateBase): pass class PromptTemplateResponse(PromptTemplateBase): id: int user_id: int created_at: datetime class Config: from_attributes = True class NaturalLanguageSortRequest(BaseModel): prompt_text: str