TradingAgents/backend/app/db/models.py

103 lines
3.2 KiB
Python

"""
Database models for users, settings, and reports
"""
import uuid
from datetime import datetime
from typing import Optional
from sqlalchemy import String, Text, DateTime, ForeignKey, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID
from .database import Base
class User(Base):
"""User model for storing Google OAuth users"""
__tablename__ = "users"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4
)
google_id: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
avatar_url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
created_at: Mapped[datetime] = mapped_column(
DateTime,
default=datetime.utcnow,
nullable=False
)
last_login_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
# Relationships
settings: Mapped[Optional["UserSettings"]] = relationship(
"UserSettings",
back_populates="user",
uselist=False,
cascade="all, delete-orphan"
)
reports: Mapped[list["Report"]] = relationship(
"Report",
back_populates="user",
cascade="all, delete-orphan"
)
class UserSettings(Base):
"""User settings (encrypted API keys, custom base URLs)"""
__tablename__ = "user_settings"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4
)
user_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
unique=True,
nullable=False
)
# Store settings as encrypted JSON string
encrypted_settings: Mapped[str] = mapped_column(Text, nullable=False)
updated_at: Mapped[datetime] = mapped_column(
DateTime,
default=datetime.utcnow,
onupdate=datetime.utcnow,
nullable=False
)
# Relationship
user: Mapped["User"] = relationship("User", back_populates="settings")
class Report(Base):
"""Analysis report storage"""
__tablename__ = "reports"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4
)
user_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False
)
ticker: Mapped[str] = mapped_column(String(20), nullable=False)
market_type: Mapped[str] = mapped_column(String(10), nullable=False) # us, twse, tpex
analysis_date: Mapped[str] = mapped_column(String(10), nullable=False) # YYYY-MM-DD
# Store full result as JSONB
result: Mapped[dict] = mapped_column(JSON, nullable=False)
created_at: Mapped[datetime] = mapped_column(
DateTime,
default=datetime.utcnow,
nullable=False
)
# Relationship
user: Mapped["User"] = relationship("User", back_populates="reports")