[verified] Sources table auto-derived from FACTORS registry + next-update column
- _build_sources now iterates FACTORS registry (grouped by fetch module) instead of hardcoded 5-row list -> adding a FACTOR auto-appends its source row (single source of truth, answers 'เพิ่มแหล่งควรอัตโนมัติ') - Each source row gains ความถี่ + อัปเดตครั้งต่อไป (from frequency cadence) - Frontend sources table: 6 columns (ข้อมูล/แหล่ง/ช่วงข้อมูล/ความถี่/อัปเดตครั้งต่อไป/อัปเดตล่าสุด), all from /api/v1/dashboard (not mock) - Verified live: 5 sources auto-derived w/ next-update; browser shows 6 cols
This commit is contained in:
@@ -332,18 +332,86 @@ class RealDashboard:
|
||||
return board
|
||||
|
||||
def _build_sources(self, auto_d, npl_d, en_d, macro_d, tourism) -> list:
|
||||
"""Sources derived from the FACTORS registry — adding a factor to
|
||||
factors.py auto-appends its source row here (no hardcoded list)."""
|
||||
import datetime as _dt
|
||||
from app import factors as factors_mod
|
||||
now = _dt.datetime.now(_dt.timezone.utc).isoformat(timespec="minutes")
|
||||
rows = [
|
||||
{"จาก": "สินเชื่อรถยนต์ (ยอดขายรถ)", "แหล่ง": "TradingEconomics", "ข้อมูล": auto_d.get("as_of", "น่าล่าสุด")},
|
||||
{"จาก": "NPL รถยนต์", "แหล่ง": "BOT FI_NP_003_S2", "ข้อมูล": npl_d.get("period", "รายไตรมาส")},
|
||||
{"จาก": "โรงกลั่น (TOP)", "แหล่ง": "Thai Oil investor", "ข้อมูล": "รายไตรมาส"},
|
||||
{"จาก": "ภาพรวมประเทศไทย", "แหล่ง": "BOT Thai Economy", "ข้อมูล": "รายเดือน"},
|
||||
]
|
||||
for r in rows:
|
||||
r["dึงมาเมื่อ"] = now
|
||||
# append tourism source if present
|
||||
|
||||
fetched = {
|
||||
"auto_credit": auto_d, "auto_npl": npl_d,
|
||||
"energy_thai": en_d, "macro_thai": macro_d,
|
||||
}
|
||||
# group FACTORS by fetch module -> one row per distinct source
|
||||
source_by_module: dict = {}
|
||||
for fkey, f in factors_mod.FACTORS.items():
|
||||
mod = f.get("fetch")
|
||||
if not mod:
|
||||
continue
|
||||
if mod not in source_by_module:
|
||||
source_by_module[mod] = {
|
||||
"mod": mod,
|
||||
"source": f.get("source", mod),
|
||||
"freq": f.get("frequency", "monthly"),
|
||||
"factors": [],
|
||||
}
|
||||
source_by_module[mod]["factors"].append(fkey)
|
||||
|
||||
# next-update cadence per frequency (hours)
|
||||
_cadence = {"daily": 24, "monthly": 24 * 30, "quarterly": 24 * 91,
|
||||
"annual": 24 * 365, "weekly": 24 * 7}
|
||||
|
||||
rows = []
|
||||
for mod, meta in source_by_module.items():
|
||||
data = fetched.get(mod) or {}
|
||||
_source_label = {
|
||||
"auto_credit": "TradingEconomics",
|
||||
"auto_npl": "BOT FI_NP_003_S2",
|
||||
"energy_thai": "Thai Oil investor",
|
||||
"macro_thai": "BOT Thai Economy",
|
||||
"bot_tourism": "BOT Tourism",
|
||||
}
|
||||
freq = meta["freq"]
|
||||
as_of = data.get("as_of") or data.get("period") or _period(data, meta["factors"])
|
||||
next_in_h = _cadence.get(freq, 24 * 30)
|
||||
next_at = (now_plus(now, next_in_h))
|
||||
rows.append({
|
||||
"แหล่ง": _source_label.get(mod, meta["source"]),
|
||||
"ขอบเขต": " | ".join(factors_mod.FACTORS[k]["name_th"] for k in meta["factors"]),
|
||||
"ข้อมูล": as_of or "",
|
||||
"ความถี่": freq_th(freq),
|
||||
"อัปเดตครั้งต่อไป": next_at,
|
||||
"dึงมาเมื่อ": now,
|
||||
})
|
||||
# tourism (fetched separately)
|
||||
if tourism and isinstance(tourism, dict):
|
||||
rows.append({"จาก": "ท่องเที่ยว", "แหล่ง": tourism.get("source", {}).get("source_id", "BOT"),
|
||||
"ข้อมูล": tourism.get("period", ""), "dึงมาเมื่อ": now})
|
||||
rows.insert(0, {
|
||||
"แหล่ง": "BOT Tourism",
|
||||
"ขอบเขต": "นักท่องเที่ยว",
|
||||
"ข้อมูล": tourism.get("period", "") or "",
|
||||
"ความถี่": "รายเดือน",
|
||||
"อัปเดตครั้งต่อไป": now_plus(now, 24 * 30),
|
||||
"dึงมาเมื่อ": now,
|
||||
})
|
||||
return rows
|
||||
|
||||
|
||||
def now_plus(iso_now: str, hours: float) -> str:
|
||||
import datetime as _dt
|
||||
base = _dt.datetime.fromisoformat(iso_now)
|
||||
return (base + _dt.timedelta(hours=hours)).isoformat(timespec="minutes")
|
||||
|
||||
|
||||
def freq_th(freq: str) -> str:
|
||||
return {"daily": "รายวัน", "weekly": "รายสัปดาห์", "monthly": "รายเดือน",
|
||||
"quarterly": "รายไตรมาส", "annual": "รายปี"}.get(freq, freq)
|
||||
|
||||
|
||||
def _period(data: dict, factor_keys: list) -> str:
|
||||
from app import factors as factors_mod
|
||||
for k in factor_keys:
|
||||
f = factors_mod.FACTORS.get(k, {})
|
||||
vk = f.get("value_key")
|
||||
if vk and data.get(vk) is not None:
|
||||
return f.get("name_th", k)
|
||||
return "--"
|
||||
|
||||
@@ -549,14 +549,16 @@ onMounted(loadDashboard)
|
||||
<table class="source-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ข้อมูล</th><th>แหล่ง</th><th>ช่วงข้อมูล</th><th>อัปเดต</th>
|
||||
<th>ข้อมูล</th><th>แหล่ง</th><th>ช่วงข้อมูล</th><th>ความถี่</th><th>อัปเดตครั้งต่อไป</th><th>อัปเดตล่าสุด</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(s, i) in dashboardSources" :key="i">
|
||||
<td>{{ s['จาก'] }}</td>
|
||||
<td>{{ s['จาก'] || s['ขอบเขต'] }}</td>
|
||||
<td class="source-name">{{ s['แหล่ง'] }}</td>
|
||||
<td class="muted-cell">{{ s['ข้อมูล'] }}</td>
|
||||
<td class="muted-cell">{{ s['ความถี่'] || '—' }}</td>
|
||||
<td class="muted-cell">{{ s['อัปเดตครั้งต่อไป'] ? formatDate(s['อัปเดตครั้งต่อไป']) : '—' }}</td>
|
||||
<td class="muted-cell">{{ s['dึงมาเมื่อ'] ? formatDate(s['dึงมาเมื่อ']) : '—' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user