Files
virtual_board_member/app/models/user.py
Jonathan Pressnell 1a8ec37bed feat: Complete Week 2 - Document Processing Pipeline
- Implement multi-format document support (PDF, XLSX, CSV, PPTX, TXT, Images)
- Add S3-compatible storage service with tenant isolation
- Create document organization service with hierarchical folders and tagging
- Implement advanced document processing with table/chart extraction
- Add batch upload capabilities (up to 50 files)
- Create comprehensive document validation and security scanning
- Implement automatic metadata extraction and categorization
- Add document version control system
- Update DEVELOPMENT_PLAN.md to mark Week 2 as completed
- Add WEEK2_COMPLETION_SUMMARY.md with detailed implementation notes
- All tests passing (6/6) - 100% success rate
2025-08-08 15:47:43 -04:00

102 lines
3.4 KiB
Python

"""
User model for authentication and user management.
"""
from datetime import datetime
from typing import Optional
from sqlalchemy import Column, String, DateTime, Boolean, Text, Enum, ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
import uuid
import enum
from app.core.database import Base
class UserRole(str, enum.Enum):
"""User roles for access control."""
BOARD_MEMBER = "board_member"
EXECUTIVE = "executive"
EXECUTIVE_ASSISTANT = "executive_assistant"
ANALYST = "analyst"
AUDITOR = "auditor"
ADMIN = "admin"
class User(Base):
"""User model for authentication and user management."""
__tablename__ = "users"
# Primary key
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
# User identification
email = Column(String(255), unique=True, nullable=False, index=True)
username = Column(String(100), unique=True, nullable=True, index=True)
# Authentication
hashed_password = Column(String(255), nullable=True) # Null for OAuth users
is_active = Column(Boolean, default=True)
is_verified = Column(Boolean, default=False)
# User information
first_name = Column(String(100), nullable=False)
last_name = Column(String(100), nullable=False)
full_name = Column(String(200), nullable=False)
# Role and permissions
role = Column(Enum(UserRole), nullable=False, default=UserRole.EXECUTIVE)
department = Column(String(100), nullable=True)
permissions = Column(Text, nullable=True) # JSON string of permissions
# Contact information
phone = Column(String(20), nullable=True)
company = Column(String(200), nullable=True)
job_title = Column(String(100), nullable=True)
# OAuth information
oauth_provider = Column(String(50), nullable=True) # auth0, cognito, etc.
oauth_id = Column(String(255), nullable=True)
# Tenant relationship
tenant_id = Column(UUID(as_uuid=True), ForeignKey("tenants.id"), nullable=False)
# Timestamps
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
last_login_at = Column(DateTime, nullable=True)
# Preferences
timezone = Column(String(50), default="UTC")
language = Column(String(10), default="en")
notification_preferences = Column(Text, nullable=True) # JSON string
# Relationships (commented out until Tenant relationships are fully implemented)
# tenant = relationship("Tenant", back_populates="users")
def __repr__(self) -> str:
return f"<User(id={self.id}, email='{self.email}', role='{self.role}')>"
@property
def display_name(self) -> str:
"""Get user's display name."""
return self.full_name or f"{self.first_name} {self.last_name}"
def has_permission(self, permission: str) -> bool:
"""Check if user has specific permission."""
# TODO: Implement permission checking logic
return True
def is_board_member(self) -> bool:
"""Check if user is a board member."""
return self.role == UserRole.BOARD_MEMBER
def is_executive(self) -> bool:
"""Check if user is an executive."""
return self.role in [UserRole.BOARD_MEMBER, UserRole.EXECUTIVE]
def is_admin(self) -> bool:
"""Check if user is an admin."""
return self.role == UserRole.ADMIN