Skip to content

Latest commit

 

History

History
418 lines (349 loc) · 18.3 KB

File metadata and controls

418 lines (349 loc) · 18.3 KB

ChainInsight 動態即時串流儀表板 — 架構升級方案

現狀分析

目前的 ChainInsight 是一個 批次處理 (Batch Processing) 架構:

CSV 輸入 → ETL 清洗 → 統計分析 → 供應鏈優化 → ML 分析 → 23 張 PNG → 靜態 HTML 儀表板

每次都要手動跑 5 個 Python 腳本,圖表是靜態 PNG,儀表板只能讀已存在的圖和 CSV。


目標架構:Event-Driven Streaming Pipeline

                    ┌─────────────────────────────────────────────────┐
                    │            ChainInsight Live Platform            │
                    └─────────────────────────────────────────────────┘

  ┌──────────────┐     ┌──────────────┐     ┌───────────────────────┐
  │  Data Source  │────▸│  Ingestion   │────▸│   Event Bus / Queue   │
  │              │     │   Gateway    │     │  (Redis Stream /      │
  │ • CSV Upload │     │              │     │   Celery / RQ)        │
  │ • API Push   │     │ • Validate   │     │                       │
  │ • ERP/WMS    │     │ • Timestamp  │     │ • on_data_arrived     │
  │ • Scheduled  │     │ • Queue      │     │ • on_etl_complete     │
  │   Polling    │     │              │     │ • on_analysis_done    │
  └──────────────┘     └──────────────┘     └──────────┬────────────┘
                                                       │
                    ┌──────────────────────────────────┐│
                    │        Pipeline Orchestrator      ││
                    │        (自動觸發流程)              │◂┘
                    └──────┬───────┬───────┬───────┬───┘
                           │       │       │       │
                    ┌──────▾──┐ ┌──▾─────┐ ┌▾─────┐ ┌▾──────────┐
                    │  ETL    │ │ Stats  │ │ SCM  │ │  ML + Planning  │
                    │ Pipeline│ │Analysis│ │Optim.│ │  Engine   │
                    │         │ │        │ │      │ │           │
                    │ 8-step  │ │chart   │ │EOQ   │ │ 30 algos │
                    │ cleaning│ │01-08   │ │Monte │ │ + S&OP  │
                    │         │ │Carlo │ │           │
                    └────┬────┘ └───┬────┘ └──┬───┘ └─────┬─────┘
                         │         │          │           │
                         ▾         ▾          ▾           ▾
                    ┌─────────────────────────────────────────┐
                    │          Result Store (DB/Cache)         │
                    │  • SQLite / PostgreSQL (結構化資料)       │
                    │  • Redis (即時 KPI 快取)                 │
                    │  • File Store (圖表 PNG/SVG)             │
                    └──────────────────┬──────────────────────┘
                                       │
                    ┌──────────────────▾──────────────────────┐
                    │       Real-Time Dashboard (Web)          │
                    │                                          │
                    │  ┌──────────┐  ┌──────────┐  ┌────────┐│
                    │  │WebSocket │  │ Plotly/  │  │ SSE    ││
                    │  │ Server   │  │ Echarts  │  │ Push   ││
                    │  └──────────┘  └──────────┘  └────────┘│
                    │                                          │
                    │  • KPI 即時更新 (無需刷新)                │
                    │  • 互動式圖表 (zoom/filter/drill-down)   │
                    │  • Pipeline 進度條                       │
                    │  • S&OP 情境分析即時視覺化                │
                    └──────────────────────────────────────────┘

核心升級分為 5 大模組


模組 1:Web 後端 + Pipeline Orchestrator

技術選型:FastAPI + Celery (或 RQ)

# app/main.py — FastAPI 入口
from fastapi import FastAPI, UploadFile, WebSocket
from app.pipeline import trigger_full_pipeline
from app.ws_manager import ConnectionManager

app = FastAPI(title="ChainInsight Live")
ws_manager = ConnectionManager()

@app.post("/api/ingest")
async def ingest_data(file: UploadFile):
    """新資料上傳後自動觸發完整 pipeline"""
    raw_path = save_upload(file)
    # 非同步觸發:ETL → Stats → SCM → ML → Capacity → Sensing → S&OP
    task = trigger_full_pipeline.delay(raw_path)
    return {"task_id": task.id, "status": "pipeline_started"}

@app.websocket("/ws/dashboard")
async def dashboard_ws(websocket: WebSocket):
    """WebSocket 即時推送分析結果到前端"""
    await ws_manager.connect(websocket)
    # 每個 pipeline 階段完成時推送更新

Pipeline Orchestrator(自動化流程):

# app/pipeline.py — 事件驅動的 Pipeline
from celery import chain

def trigger_full_pipeline(raw_path: str):
    """資料進來 → 自動跑完全部流程"""
    workflow = chain(
        etl_task.s(raw_path),           # Step 1: 8-step ETL
        stats_task.s(),                  # Step 2: 統計分析
        supply_chain_task.s(),           # Step 3: 供應鏈優化
        ml_task.s(),                     # Step 4: ML 30 algos
        sop_task.s(),                    # Step 5: S&OP 情境模擬
        publish_results.s(),             # Step 6: 推送到 Dashboard
    )
    return workflow.apply_async()

模組 2:即時互動式儀表板

技術選型比較:

方案 技術 優點 缺點
A (推薦) FastAPI + React/Vue + Plotly.js 完全自定義、最佳 UX、WebSocket 原生 開發量較大
B (快速) Streamlit / Dash Python 全棧、開發快 自定義受限、並行能力弱

推薦方案 A 的前端架構:

前端 (React + TypeScript)
├── components/
│   ├── KPIDashboard.tsx        # 6 個 KPI 即時卡片
│   ├── PipelineProgress.tsx    # 流程進度條 (ETL → Stats → ML → Capacity → Sensing → S&OP)
│   ├── InteractiveCharts/
│   │   ├── CorrelationMatrix.tsx   # Plotly heatmap (可互動)
│   │   ├── MonteCarloSim.tsx       # 動態 Monte Carlo 模擬
│   │   ├── EOQOptimizer.tsx        # 拖動參數即時重算 EOQ
│   │   ├── SOPScenarioViz.tsx      # S&OP 情境比較
│   │   └── InventoryHealthMap.tsx  # ABC 分類 + 風險熱力圖
│   ├── DataUploader.tsx         # 拖拽上傳 CSV
│   └── AlertPanel.tsx           # 即時缺貨警報
├── hooks/
│   └── useWebSocket.ts          # WebSocket 連線管理
└── stores/
    └── dashboardStore.ts        # 全域狀態管理

關鍵互動功能:

  • 圖表全部從靜態 PNG → Plotly.js / ECharts 互動式(zoom、filter、drill-down)
  • WebSocket 即時推送:pipeline 每階段完成 → 自動更新對應圖表
  • 參數可調:使用者可以在前端調整 EOQ 的 S/H 參數、Monte Carlo 模擬次數、GA 的代數等

模組 3:Reinforcement Learning 引擎(核心新增)

目前有 GA(遺傳演算法)做靜態安全庫存最佳化。S&OP 模擬的價值在於:它能透過情境分析比較不同策略的 KPI 表現,支持數據驅動的決策。

需求規劃應用場景設計

┌─────────────────────────────────────────────────────────┐
│             Demand Planning for Supply Chain              │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  模組 1: 產能規劃 (Capacity Planning)                    │
│  ─────────────────────────────────────────                │
│  輸入: 需求預測、產線 Profile、稼動率目標               │
│  輸出: 可行性報告、瓶頸偵測、調整建議                   │
│                                                          │
│  模組 2: 需求感知 (Demand Sensing)                       │
│  ─────────────────────────────────────────                │
│  輸入: POS 資料、社群訊號、天氣資料                     │
│  輸出: 調整後預測、需求突增偵測                         │
│                                                          │
│  模組 3: S&OP 模擬器 (S&OP Simulator)                    │
│  ─────────────────────────────────────────                │
│  輸入: 基準預測、產能限制、供應限制                     │
│  輸出: 情境比較 (Fill Rate, 庫存成本, 稼動率)           │
│                                                          │
└─────────────────────────────────────────────────────────┘

模組 4:資料持久化 + 時間序列

從單一 CSV → 資料庫 + 版本化

# app/db/models.py
from sqlalchemy import Column, Integer, Float, String, DateTime, JSON
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class InventorySnapshot(Base):
    """每次資料匯入都保存一份快照,支援時間序列分析"""
    __tablename__ = 'inventory_snapshots'
    id = Column(Integer, primary_key=True)
    ingested_at = Column(DateTime, index=True)
    batch_id = Column(String, index=True)
    product_id = Column(String, index=True)
    category = Column(String)
    unit_cost = Column(Float)
    current_stock = Column(Float)
    daily_demand_est = Column(Float)
    safety_stock_target = Column(Float)
    vendor_name = Column(String)
    lead_time_days = Column(Float)
    reorder_point = Column(Float)
    stock_status = Column(String)
    inventory_value = Column(Float)

class AnalysisResult(Base):
    """儲存每次分析結果,支援歷史比較"""
    __tablename__ = 'analysis_results'
    id = Column(Integer, primary_key=True)
    batch_id = Column(String, index=True)
    analysis_type = Column(String)
    result_json = Column(JSON)
    chart_path = Column(String)
    created_at = Column(DateTime)

class SOPScenarioResult(Base):
    """儲存 S&OP 模擬情境結果"""
    __tablename__ = 'sop_scenario_results'
    id = Column(Integer, primary_key=True)
    scenario_name = Column(String)
    batch_id = Column(String, index=True)
    fill_rate = Column(Float)
    avg_utilization = Column(Float)
    inventory_cost = Column(Float)
    stockout_events = Column(Integer)
    created_at = Column(DateTime)

有了時間序列資料,就能解鎖之前標為 N/A 的演算法:

演算法 現狀 升級後
RNN (#23) N/A (缺時間序列) 可用 — 多批次資料形成時間序列
LSTM (#24) N/A 可用 — 需求預測
Transformer (#25) N/A 可用 — 多品類注意力機制
S&OP Simulation N/A 可用 — 情境比較 + KPI 分析
Capacity Planning N/A 可用 — 瓶頸偵測 + 調整建議
Demand Sensing N/A 可用 — 訊號處理 + 預測調整

升級後:30 個演算法全部 Applied!


模組 5:自動化觸發 + 監控

# app/triggers.py — 多種資料輸入觸發方式

# 1. 檔案監控 (Watch 資料夾)
from watchdog.observers import Observer
class CSVWatcher:
    """監控指定資料夾,新 CSV 出現時自動觸發 pipeline"""
    def on_created(self, event):
        if event.src_path.endswith('.csv'):
            trigger_full_pipeline.delay(event.src_path)

# 2. 排程觸發 (每日/每小時)
from celery.schedules import crontab
CELERYBEAT_SCHEDULE = {
    'daily-inventory-sync': {
        'task': 'app.pipeline.sync_from_erp',
        'schedule': crontab(hour=6, minute=0),
    },
    'hourly-rl-update': {
        'task': 'app.pipeline.sop_refresh',
        'schedule': crontab(minute=0),
    },
}

# 3. API Webhook (ERP/WMS 主動推送)
@app.post("/webhook/inventory-update")
async def erp_webhook(payload: InventoryUpdate):
    trigger_full_pipeline.delay(payload.data)

# 4. 手動上傳 (Dashboard UI)
# → 見模組 1 的 /api/ingest 端點

技術棧總覽

層級 技術 用途
Web Framework FastAPI REST API + WebSocket
Task Queue Celery + Redis 非同步 pipeline 執行
Database SQLite (dev) → PostgreSQL (prod) 結構化資料 + 時間序列
Cache Redis 即時 KPI + Session
Planning Capacity + Sensing + S&OP 需求規劃引擎
前端 React + Plotly.js (或 Streamlit 快速版) 互動式儀表板
即時通訊 WebSocket (FastAPI 內建) 推送更新到前端
檔案監控 Watchdog 自動偵測新 CSV
排程 Celery Beat 定時觸發
容器化 Docker + docker-compose 一鍵部署

實作優先順序

Phase 1 (MVP — 最小可行產品)

① 將現有分析腳本模組化 (function-based → class-based)
② FastAPI 後端 + CSV 上傳 API
③ Pipeline orchestrator (ETL → Stats → ML 自動串接)
④ Streamlit 快速版即時儀表板 (取代靜態 HTML)
⑤ SQLite 儲存歷史分析結果

Phase 2 (需求規劃引擎)

⑥ Capacity Planning (產能規劃、瓶頸偵測)
⑦ Demand Sensing (需求訊號處理、突增偵測)
⑧ S&OP Simulator (情境模擬、KPI 比較)
⑨ 產能 vs 需求視覺化 (utilization timeline, bottleneck chart)
⑩ S&OP 情境比較視覺化 (scenario comparison, demand-supply balance)

Phase 3 (即時串流)

⑪ WebSocket 即時推送
⑫ React 互動式前端 (取代 Streamlit)
⑬ Watchdog 檔案監控自動觸發
⑭ Celery Beat 排程
⑮ 即時警報系統 (缺貨、異常)

Phase 4 (生產級)

⑯ PostgreSQL 遷移
⑰ Docker + docker-compose
⑱ LSTM/Transformer 需求預測 (需累積時間序列)
⑲ Multi-warehouse S&OP planning
⑳ CI/CD + 自動化測試

預期新目錄結構

ChainInsight/
├── app/
│   ├── main.py                  # FastAPI 入口
│   ├── config.py                # 統一設定
│   ├── pipeline/
│   │   ├── orchestrator.py      # Pipeline 排程器
│   │   ├── etl.py               # 重構的 ETL (from clean_data.py)
│   │   ├── stats.py             # 重構的統計分析
│   │   ├── supply_chain.py      # 重構的供應鏈優化
│   │   └── ml_engine.py         # 重構的 ML 分析
│   ├── capacity/
│   │   ├── models.py            # CapacityPlanner, bottleneck detection
│   │   └── visualization.py     # Utilization timeline charts
│   ├── sensing/
│   │   ├── signals.py           # SignalProcessor, spike detection
│   │   └── visualization.py     # Signal timeline charts
│   ├── sop/
│   │   ├── simulator.py         # SOPSimulator, scenario comparison
│   │   └── visualization.py     # Demand-supply balance charts
│   ├── db/
│   │   ├── models.py            # SQLAlchemy 模型
│   │   ├── session.py           # DB 連線管理
│   │   └── migrations/          # Alembic 遷移
│   ├── api/
│   │   ├── routes.py            # REST API 路由
│   │   └── websocket.py         # WebSocket 管理
│   └── services/
│       ├── chart_service.py     # 圖表產生 (Plotly)
│       ├── alert_service.py     # 警報系統
│       └── export_service.py    # PDF/Excel 匯出
├── frontend/                    # React + TypeScript (Phase 3)
│   ├── src/
│   │   ├── components/
│   │   ├── hooks/
│   │   └── stores/
│   └── package.json
├── data/
│   ├── raw/                     # 上傳的原始 CSV
│   ├── clean/                   # ETL 清洗後
│   └── charts/                  # 產生的圖表
├── tests/
├── docker-compose.yml
├── requirements.txt             # 更新的依賴
└── README.md

升級前後對比

面向 現在 升級後
觸發方式 手動跑 5 個腳本 上傳 CSV / API / 排程自動觸發
圖表 23 張靜態 PNG 互動式 Plotly (zoom/filter/drill-down)
儀表板 靜態 HTML 讀 CSV WebSocket 即時串流更新
最佳化 GA 一次性計算 GA 全域搜索 + S&OP 情境模擬
ML 覆蓋 20/30 演算法 30/30 全部 Applied
資料儲存 單一 CSV DB + 時間序列 + 歷史版本
部署 python xxx.py Docker 一鍵啟動