File size: 6,183 Bytes
abf702c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy import String, Integer, ForeignKey, Float, DateTime
from app.db.session import Base
from typing import List
import datetime

class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    email: Mapped[str] = mapped_column(String, unique=True, index=True)
    username: Mapped[str] = mapped_column(String, unique=True, index=True, nullable=True)
    full_name: Mapped[str] = mapped_column(String)
    avatar_url: Mapped[str] = mapped_column(String, nullable=True)
    google_id: Mapped[str] = mapped_column(String, unique=True, index=True, nullable=True)
    theme: Mapped[str] = mapped_column(String, default="dark", nullable=True)
    
    # Relationships
    indicators: Mapped[List["UserIndicator"]] = relationship("UserIndicator", back_populates="user", cascade="all, delete-orphan")
    watchlist: Mapped[List["WatchlistItem"]] = relationship("WatchlistItem", back_populates="user", cascade="all, delete-orphan")
    universe: Mapped[List["UniverseItem"]] = relationship("UniverseItem", back_populates="user", cascade="all, delete-orphan")
    ai_models: Mapped[List["UserAIModel"]] = relationship("UserAIModel", back_populates="user", cascade="all, delete-orphan")
    sessions: Mapped[List["UserSession"]] = relationship("UserSession", back_populates="user", cascade="all, delete-orphan")
    agentic_scans: Mapped[List["UserAgenticScan"]] = relationship("UserAgenticScan", back_populates="user", cascade="all, delete-orphan")

class WatchlistItem(Base):
    __tablename__ = "watchlist"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
    symbol: Mapped[str] = mapped_column(String, index=True)
    name: Mapped[str] = mapped_column(String)
    exchange: Mapped[str] = mapped_column(String, nullable=True)
    
    user: Mapped["User"] = relationship("User", back_populates="watchlist")

class UniverseItem(Base):
    __tablename__ = "universe"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
    symbol: Mapped[str] = mapped_column(String, index=True)
    name: Mapped[str] = mapped_column(String)
    last_updated: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime.utcnow)
    
    user: Mapped["User"] = relationship("User", back_populates="universe")

class HistoricalData(Base):
    __tablename__ = "historical_data"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    symbol: Mapped[str] = mapped_column(String, index=True)
    date: Mapped[datetime.datetime] = mapped_column(DateTime, index=True)
    open: Mapped[float] = mapped_column(Float)
    high: Mapped[float] = mapped_column(Float)
    low: Mapped[float] = mapped_column(Float)
    close: Mapped[float] = mapped_column(Float)
    volume: Mapped[float] = mapped_column(Float)
    # Storing indicators as JSON string for flexibility
    indicators: Mapped[str] = mapped_column(String, nullable=True)

class UserIndicator(Base):
    __tablename__ = "user_indicators"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
    indicator_id: Mapped[str] = mapped_column(String, index=True)
    category: Mapped[str] = mapped_column(String)
    enabled: Mapped[bool] = mapped_column(Integer, default=1) # 1 for True in SQLite
    
    user: Mapped["User"] = relationship("User", back_populates="indicators")

class UserAIModel(Base):
    __tablename__ = "user_ai_models"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
    name: Mapped[str] = mapped_column(String)
    model_type: Mapped[str] = mapped_column(String) # 'RandomForest', 'LSTM', etc.
    created_at: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime.utcnow)
    target_symbol: Mapped[str] = mapped_column(String)
    
    # Store configuration and results as JSON
    parameters: Mapped[str] = mapped_column(String, nullable=True) # JSON
    metrics: Mapped[str] = mapped_column(String, nullable=True) # JSON {mse: 0.1, r2: 0.8}
    file_path: Mapped[str] = mapped_column(String, nullable=True) # Path to .joblib or .h5 file

    user: Mapped["User"] = relationship("User", back_populates="ai_models")

class UserSession(Base):
    __tablename__ = "user_sessions"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
    login_at: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime.utcnow)
    logout_at: Mapped[datetime.datetime] = mapped_column(DateTime, nullable=True)
    ip_address: Mapped[str] = mapped_column(String, nullable=True)
    user_agent: Mapped[str] = mapped_column(String, nullable=True)
    
    user: Mapped["User"] = relationship("User", back_populates="sessions")

class UserAgenticScan(Base):
    __tablename__ = "user_agentic_scans"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"))
    symbol: Mapped[str] = mapped_column(String, index=True)
    decision: Mapped[str] = mapped_column(String) # 'TRADE' or 'WAIT'
    confidence: Mapped[float] = mapped_column(Float)
    recommendation: Mapped[str] = mapped_column(String)
    entry_price: Mapped[str] = mapped_column(String, nullable=True)
    created_at: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime.utcnow)
    
    # Store full analysis as JSON
    raw_logs: Mapped[str] = mapped_column(String, nullable=True) # JSON Logs
    risk_warning: Mapped[str] = mapped_column(String, nullable=True)

    user: Mapped["User"] = relationship("User", back_populates="agentic_scans")