apersona/backend/app/db/models.py

149 lines
5.9 KiB
Python

from sqlalchemy import Boolean, Column, Integer, String, DateTime, Text, Float, ForeignKey, JSON
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.db.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True, nullable=False)
email = Column(String, unique=True, index=True, nullable=False)
hashed_password = Column(String, nullable=False)
full_name = Column(String, nullable=True)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
last_login = Column(DateTime(timezone=True), nullable=True)
# Relationships
files = relationship("UserFile", back_populates="owner")
interactions = relationship("UserInteraction", back_populates="user")
preferences = relationship("UserPreference", back_populates="user")
reminders = relationship("Reminder", back_populates="user")
class UserFile(Base):
__tablename__ = "user_files"
id = Column(Integer, primary_key=True, index=True)
filename = Column(String, nullable=False)
original_name = Column(String, nullable=False)
file_path = Column(String, nullable=False)
file_type = Column(String, nullable=False) # pdf, txt, docx, image, etc.
file_size = Column(Integer, nullable=False)
mime_type = Column(String, nullable=True)
# Content analysis
content_summary = Column(Text, nullable=True)
extracted_text = Column(Text, nullable=True)
categories = Column(JSON, nullable=True) # List of auto-detected categories
tags = Column(JSON, nullable=True) # User-defined tags
# Metadata
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
last_accessed = Column(DateTime(timezone=True), nullable=True)
access_count = Column(Integer, default=0)
# Relationships
owner_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="files")
class UserInteraction(Base):
__tablename__ = "user_interactions"
id = Column(Integer, primary_key=True, index=True)
interaction_type = Column(String, nullable=False) # query, file_upload, search, etc.
query = Column(Text, nullable=True)
response = Column(Text, nullable=True)
context = Column(JSON, nullable=True) # Additional context data
# Quality metrics
response_time = Column(Float, nullable=True)
user_feedback = Column(Integer, nullable=True) # -1, 0, 1 (negative, neutral, positive)
was_helpful = Column(Boolean, nullable=True)
# Learning data
used_files = Column(JSON, nullable=True) # List of file IDs used in response
search_terms = Column(JSON, nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
user_id = Column(Integer, ForeignKey("users.id"))
user = relationship("User", back_populates="interactions")
class UserPreference(Base):
__tablename__ = "user_preferences"
id = Column(Integer, primary_key=True, index=True)
preference_type = Column(String, nullable=False) # response_style, categories, etc.
preference_key = Column(String, nullable=False)
preference_value = Column(JSON, nullable=False)
confidence_score = Column(Float, default=0.5) # How confident we are about this preference
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
user_id = Column(Integer, ForeignKey("users.id"))
user = relationship("User", back_populates="preferences")
class Reminder(Base):
__tablename__ = "reminders"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, nullable=False)
description = Column(Text, nullable=True)
reminder_time = Column(DateTime(timezone=True), nullable=False)
is_completed = Column(Boolean, default=False)
is_recurring = Column(Boolean, default=False)
recurrence_pattern = Column(String, nullable=True) # daily, weekly, monthly
# Context for AI suggestions
context_files = Column(JSON, nullable=True) # Related file IDs
auto_generated = Column(Boolean, default=False) # Was this generated by AI?
priority = Column(Integer, default=1) # 1-5 priority scale
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
user_id = Column(Integer, ForeignKey("users.id"))
user = relationship("User", back_populates="reminders")
class LearningPattern(Base):
__tablename__ = "learning_patterns"
id = Column(Integer, primary_key=True, index=True)
pattern_type = Column(String, nullable=False) # time_based, topic_based, etc.
pattern_data = Column(JSON, nullable=False)
confidence_score = Column(Float, default=0.0)
usage_count = Column(Integer, default=0)
success_rate = Column(Float, default=0.0)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
user_id = Column(Integer, ForeignKey("users.id"))
class DocumentEmbedding(Base):
__tablename__ = "document_embeddings"
id = Column(Integer, primary_key=True, index=True)
file_id = Column(Integer, ForeignKey("user_files.id"))
chunk_index = Column(Integer, nullable=False) # For large documents split into chunks
chunk_text = Column(Text, nullable=False)
embedding_id = Column(String, nullable=False) # ID in vector database
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
file = relationship("UserFile")