Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
3.8 KiB
Python
108 lines
3.8 KiB
Python
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Text, UniqueConstraint
|
|
from sqlalchemy.orm import relationship, declarative_base
|
|
from datetime import datetime
|
|
|
|
Base = declarative_base()
|
|
|
|
class Category(Base):
|
|
__tablename__ = 'categories'
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(String(50), unique=True, nullable=False)
|
|
products = relationship("Product", back_populates="category_rel")
|
|
|
|
class Product(Base):
|
|
__tablename__ = 'products'
|
|
id = Column(Integer, primary_key=True)
|
|
i_code = Column(String(50), unique=True, nullable=False, index=True)
|
|
name = Column(String(255), nullable=False)
|
|
url = Column(String(500))
|
|
image_url = Column(Text)
|
|
category = Column(String(100))
|
|
|
|
# V9.52 新增欄位
|
|
status = Column(String(20), default='ACTIVE')
|
|
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
# 關聯設定
|
|
category_id = Column(Integer, ForeignKey('categories.id'))
|
|
category_rel = relationship("Category", back_populates="products")
|
|
prices = relationship("PriceRecord", back_populates="product", cascade="all, delete-orphan")
|
|
|
|
class PriceRecord(Base):
|
|
__tablename__ = 'price_records'
|
|
id = Column(Integer, primary_key=True)
|
|
product_id = Column(Integer, ForeignKey('products.id'), nullable=False)
|
|
price = Column(Float, nullable=False)
|
|
timestamp = Column(DateTime, default=datetime.now, index=True)
|
|
product = relationship("Product", back_populates="prices")
|
|
|
|
class MonthlySummaryAnalysis(Base):
|
|
__tablename__ = 'monthly_summary_analysis'
|
|
id = Column(Integer, primary_key=True)
|
|
year = Column(Integer, nullable=False, index=True)
|
|
month = Column(Integer, nullable=False, index=True)
|
|
department = Column(String(100))
|
|
category_3c = Column(String(100))
|
|
division = Column(String(100), index=True)
|
|
section = Column(String(100))
|
|
area_id = Column(String(50))
|
|
area_name = Column(String(100))
|
|
pm_name = Column(String(100), index=True)
|
|
brand_name = Column(String(200), index=True)
|
|
vendor_id = Column(Integer, index=True)
|
|
vendor_name = Column(String(200))
|
|
trade_type = Column(String(20))
|
|
unit_price = Column(Float)
|
|
|
|
# 指標 - 銷售額
|
|
sales_amt_curr = Column(Integer)
|
|
sales_amt_prev = Column(Integer)
|
|
sales_amt_yoa = Column(Integer)
|
|
|
|
# 指標 - 毛1額
|
|
profit_amt_curr = Column(Integer)
|
|
profit_amt_prev = Column(Integer)
|
|
profit_amt_yoa = Column(Integer)
|
|
|
|
# 指標 - 折扣金額
|
|
discount_amt_curr = Column(Integer)
|
|
discount_amt_prev = Column(Integer)
|
|
discount_amt_yoa = Column(Integer)
|
|
|
|
# 指標 - 折價券
|
|
coupon_amt_curr = Column(Integer)
|
|
coupon_amt_prev = Column(Integer)
|
|
coupon_amt_yoa = Column(Integer)
|
|
|
|
# 指標 - 其他行銷活動
|
|
other_mkt_curr = Column(Integer)
|
|
other_mkt_prev = Column(Integer)
|
|
other_mkt_yoa = Column(Integer)
|
|
|
|
# 指標 - 點我折
|
|
spot_disc_curr = Column(Integer)
|
|
spot_disc_prev = Column(Integer)
|
|
spot_disc_yoa = Column(Integer)
|
|
|
|
# 指標 - 點數折抵
|
|
point_disc_curr = Column(Integer)
|
|
point_disc_prev = Column(Integer)
|
|
point_disc_yoa = Column(Integer)
|
|
|
|
# 指標 - 銷售量
|
|
sales_vol_curr = Column(Integer)
|
|
sales_vol_prev = Column(Integer)
|
|
sales_vol_yoa = Column(Integer)
|
|
|
|
# 指標 - 轉換率與瀏覽數
|
|
conv_rate = Column(Float)
|
|
views_curr = Column(Integer)
|
|
views_prev = Column(Integer)
|
|
views_yoa = Column(Integer)
|
|
|
|
created_at = Column(DateTime, default=datetime.now)
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint('year', 'month', 'department', 'category_3c', 'division', 'section', 'area_id', 'pm_name', 'brand_name', 'vendor_id', 'trade_type', name='_monthly_summary_uc'),
|
|
) |