File size: 4,159 Bytes
a600665
381775d
5840851
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a600665
 
 
5840851
 
 
a600665
 
5840851
a600665
5840851
 
a600665
5840851
a600665
 
5840851
a600665
 
 
 
5840851
a600665
 
 
 
 
 
 
 
5840851
a600665
 
5840851
 
381775d
 
 
 
 
5840851
8200518
 
 
 
 
 
 
 
 
 
 
 
5840851
8200518
5840851
 
8200518
 
 
a600665
5840851
 
8200518
 
5840851
 
 
 
 
 
 
 
ffd99f4
 
 
 
 
 
 
 
 
 
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
from datetime import datetime, timedelta
from sqlalchemy import Column, String, Integer, Float, Boolean, DateTime, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import declarative_base

Base = declarative_base()


class Company(Base):
    """์ƒ์žฅ์‚ฌ ๊ธฐ๋ณธ ์ •๋ณด. ์šฐ์„ ์ฃผ๋Š” ์ˆ˜์ง‘ ์‹œ skip."""
    __tablename__ = "company"

    ticker = Column(String, primary_key=True)
    corp_code = Column(String)        # DART corp_code (8์ž๋ฆฌ)
    name = Column(String, nullable=False)
    market = Column(String)           # KOSPI / KOSDAQ
    fiscal_year_end = Column(Integer, default=12)  # ๊ฒฐ์‚ฐ์›” (12=12์›” ๊ฒฐ์‚ฐ)


class PriceSnapshot(Base):
    """ํ˜„์žฌ ์ฃผ๊ฐ€ + ์‹œ๊ฐ€์ด์•ก. ๋„ค์ด๋ฒ„ ์ปจ์„ผ์„œ์Šค ์ˆ˜์ง‘ ์‹œ ํ•จ๊ป˜ ์ €์žฅ."""
    __tablename__ = "price_snapshot"

    ticker = Column(String, ForeignKey("company.ticker"), primary_key=True)
    current_price = Column(Float)
    market_cap = Column(Float)        # ์–ต์›
    updated_at = Column(DateTime)


class AnnualData(Base):
    """์—ฐ๊ฐ„ ์žฌ๋ฌด ๋ฐ์ดํ„ฐ. ํ™•์ •์‹ค์ (is_estimate=False)๊ณผ ์ปจ์„ผ์„œ์Šค(is_estimate=True) ํ†ตํ•ฉ."""
    __tablename__ = "annual_data"

    id = Column(Integer, primary_key=True, autoincrement=True)
    ticker = Column(String, ForeignKey("company.ticker"), nullable=False)
    year = Column(Integer, nullable=False)
    is_estimate = Column(Boolean, nullable=False, default=False)

    # ์‹ค์ 
    revenue = Column(Float)           # ๋งค์ถœ์•ก (์–ต์›)
    op_income = Column(Float)         # ์˜์—…์ด์ต (์–ต์›)
    net_income = Column(Float)        # ๋‹น๊ธฐ์ˆœ์ด์ต (์–ต์›) โ€” ํ™•์ •๋งŒ

    # ์ฃผ๋‹น ์ง€ํ‘œ
    eps = Column(Float)               # EPS (์›)
    bps = Column(Float)               # BPS (์›)
    dividend_per_share = Column(Float) # ์ฃผ๋‹น๋ฐฐ๋‹น๊ธˆ (์›)
    dividend_yield = Column(Float)    # ๋ฐฐ๋‹น์ˆ˜์ต๋ฅ  (%)

    # ์žฌ๋ฌด์ƒํƒœ
    equity = Column(Float)            # ์ž๋ณธ์ด๊ณ„ (์–ต์›)
    total_assets = Column(Float)      # ์ž์‚ฐ์ด๊ณ„ (์–ต์›)
    shares_outstanding = Column(Float)

    # ์•ˆ์ •์„ฑ ๋น„์œจ โ€” ํ™•์ •์—ฐ๋„๋งŒ (์ถ”์ •์—ฐ๋„๋Š” NULL)
    roe = Column(Float)               # ROE (%)
    roa = Column(Float)               # ROA (%)
    debt_ratio = Column(Float)        # ๋ถ€์ฑ„๋น„์œจ (%)
    interest_bearing_debt = Column(Float)  # ์ด์ž๋ฐœ์ƒ๋ถ€์ฑ„ (์–ต์›)

    # ๋ฉ”ํƒ€
    is_stale = Column(Boolean, default=False)
    updated_at = Column(DateTime)

    __table_args__ = (
        Index("ix_annual_data_ticker_year_is_estimate", "ticker", "year", "is_estimate"),
        Index("ix_annual_data_ticker_is_estimate", "ticker", "is_estimate"),
    )


class User(Base):
    """Google OAuth ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž."""
    __tablename__ = "user"

    id = Column(Integer, primary_key=True, autoincrement=True)
    google_id = Column(String, unique=True, nullable=False)
    email = Column(String, nullable=False)
    name = Column(String)
    is_admin = Column(Boolean, default=False)
    created_at = Column(DateTime, default=lambda: datetime.utcnow() + timedelta(hours=9))


class Watchlist(Base):
    """๊ด€์‹ฌ์ข…๋ชฉ. ์‚ฌ์šฉ์ž๋ณ„ ๊ฒฉ๋ฆฌ."""
    __tablename__ = "watchlist"

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
    ticker = Column(String, ForeignKey("company.ticker"), nullable=False)
    added_at = Column(DateTime, default=lambda: datetime.utcnow() + timedelta(hours=9))
    memo = Column(String, default="")

    __table_args__ = (UniqueConstraint("user_id", "ticker"),)


class BondRate(Base):
    """๊ตญ์ฑ„ 10๋…„๋ฌผ ๊ธˆ๋ฆฌ. ๋‹จ์ผ row (id=1) upsert."""
    __tablename__ = "bond_rate"

    id = Column(Integer, primary_key=True, default=1)
    rate = Column(Float, nullable=False)   # % (์˜ˆ: 3.2)
    fetched_at = Column(DateTime)


class Feedback(Base):
    """์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ/๋Œ“๊ธ€."""
    __tablename__ = "feedback"

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
    content = Column(String, nullable=False)
    created_at = Column(DateTime, default=lambda: datetime.utcnow() + timedelta(hours=9))