Newer
Older
cortex-hub / ai-hub / app / db / models / user.py
from datetime import datetime
from sqlalchemy import Column, Integer, String, JSON, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from ..database import Base

class Group(Base):
    __tablename__ = 'groups'

    id = Column(String, primary_key=True, index=True)
    name = Column(String, unique=True, nullable=False)
    description = Column(String, nullable=True)
    policy = Column(JSON, default={}, server_default='{}', nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)

    users = relationship("User", back_populates="group")

    def __repr__(self):
        return f"<Group(id={self.id}, name='{self.name}')>"

class User(Base):
    __tablename__ = 'users'

    id = Column(String, primary_key=True, index=True)
    oidc_id = Column(String, unique=True, nullable=True)
    email = Column(String, nullable=True)
    username = Column(String, nullable=True)
    password_hash = Column(String, nullable=True)
    full_name = Column(String, nullable=True)
    role = Column(String, default="user", nullable=False)
    group_id = Column(String, ForeignKey('groups.id'), nullable=True)
    avatar_url = Column(String, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    last_login_at = Column(DateTime, default=datetime.utcnow)
    preferences = Column(JSON, default={}, nullable=True)

    group = relationship("Group", back_populates="users")
    sessions = relationship("Session", back_populates="user", cascade="all, delete-orphan")

    def __repr__(self):
        return f"<User(id={self.id}, email='{self.email}')>"


class SystemConfig(Base):
    """System-wide configuration, decoupled from any user account.
    Admins write here; all users inherit these as their baseline."""
    __tablename__ = "system_config"

    key = Column(String, primary_key=True)   # "llm" | "tts" | "stt"
    value = Column(JSON, default={}, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    updated_by = Column(String, ForeignKey("users.id"), nullable=True)  # audit trail