buildersai / app /database /models.py
Kushal
Fix: Sync missing report routes and templates for production
6621cba
Raw
History Blame Contribute Delete
6.08 kB
from sqlalchemy import Column, String, Integer, Text, DateTime, ForeignKey, CheckConstraint
from sqlalchemy.orm import relationship
from datetime import datetime
import uuid
from app.database.connection import Base
def generate_id():
"""Generate a unique ID."""
return str(uuid.uuid4())
class User(Base):
"""User model for authentication."""
__tablename__ = "users"
id = Column(String, primary_key=True, default=generate_id)
email = Column(String, unique=True, nullable=False, index=True)
name = Column(String, nullable=True)
password_hash = Column(String, nullable=True) # Nullable for OAuth users
google_id = Column(String, unique=True, nullable=True, index=True)
is_admin = Column(Integer, default=0) # 0 = regular user, 1 = admin
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
sessions = relationship("Session", back_populates="user", cascade="all, delete-orphan")
documents = relationship("Document", back_populates="user", cascade="all, delete-orphan")
class Session(Base):
"""Chat session model."""
__tablename__ = "sessions"
id = Column(String, primary_key=True, default=generate_id)
user_id = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=True, index=True)
title = Column(String, default="New Conversation")
summary = Column(Text, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("User", back_populates="sessions")
messages = relationship("Message", back_populates="session", cascade="all, delete-orphan")
class Message(Base):
"""Chat message model."""
__tablename__ = "messages"
id = Column(String, primary_key=True, default=generate_id)
session_id = Column(String, ForeignKey("sessions.id", ondelete="CASCADE"), nullable=False, index=True)
role = Column(String, nullable=False) # 'user' or 'assistant'
content = Column(Text, nullable=False)
meta = Column(Text, nullable=True) # JSON string for metadata (agent, sources, etc.)
created_at = Column(DateTime, default=datetime.utcnow)
# Relationships
session = relationship("Session", back_populates="messages")
# Constraint
__table_args__ = (
CheckConstraint("role IN ('user', 'assistant')", name="check_role"),
)
class Document(Base):
"""Uploaded document model."""
__tablename__ = "documents"
id = Column(String, primary_key=True, default=generate_id)
user_id = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
filename = Column(String, nullable=False)
file_path = Column(String, nullable=False)
file_type = Column(String, nullable=True)
file_size = Column(Integer, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
# Relationships
user = relationship("User", back_populates="documents")
class OfficialPolicy(Base):
"""Official policy document model (admin-only upload, visible to all)."""
__tablename__ = "official_policies"
id = Column(String, primary_key=True, default=generate_id)
title = Column(String, nullable=False)
description = Column(Text, nullable=True)
filename = Column(String, nullable=False)
file_path = Column(String, nullable=False)
file_type = Column(String, nullable=True)
file_size = Column(Integer, nullable=True)
category = Column(String, nullable=True) # e.g., "OSHA", "Safety", "Building Codes"
uploaded_by = Column(String, ForeignKey("users.id"), nullable=False)
is_active = Column(Integer, default=1) # 0 = inactive, 1 = active
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
chunks = relationship("PolicyChunk", back_populates="policy", cascade="all, delete-orphan")
class PolicyChunk(Base):
"""Chunks of official policy text for database-backed retrieval."""
__tablename__ = "policy_chunks"
id = Column(String, primary_key=True, default=generate_id)
policy_id = Column(String, ForeignKey("official_policies.id", ondelete="CASCADE"), nullable=False, index=True)
chunk_index = Column(Integer, nullable=False)
content = Column(Text, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
# Relationships
policy = relationship("OfficialPolicy", back_populates="chunks")
class UserSettings(Base):
"""User settings and preferences model."""
__tablename__ = "user_settings"
id = Column(String, primary_key=True, default=generate_id)
user_id = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, unique=True, index=True)
# Profile settings
bio = Column(Text, nullable=True)
phone = Column(String, nullable=True)
company = Column(String, nullable=True)
# Appearance settings
theme = Column(String, default="system") # light, dark, system
# Notification settings
email_notifications = Column(Integer, default=1) # 0 = off, 1 = on
update_notifications = Column(Integer, default=1) # 0 = off, 1 = on
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Report(Base):
"""Generated reports model."""
__tablename__ = "reports"
id = Column(String, primary_key=True, default=generate_id)
user_id = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=True, index=True)
template_id = Column(String, nullable=False)
filename = Column(String, nullable=False)
file_path = Column(String, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
# Relationships
user = relationship("User")