feat(scoring): flexible source fallback (no board crash) + per-source calc audit (Q2, Q3)

Q2 flexible scoring: _fetch_with_cache now degrades instead of raising
DashboardError — a source that fails with no cached value returns {} so the
theme scorer drops that source's factors; a previously-good value is kept as
stale by the daily cache. Verified: all-sources-down still builds 13 themes.

Q3 per-source audit: new themes.factor_source_breakdown(fetched, theme) shows
per factor source/raw/normalized/weight/contribution; dashboard exposes
fetch_data + factor_sources; per-symbol modal renders symbolDetail.factor_sources
(e.g. retail: te_thailand ยอดขายปลีก -14.5 -> -1.0 x 0.7 = -0.7).

Suite 369 green; independent review passed: true.
Q1 (HAR for deferred sources) spike recorded: method works, REIC needs deeper
interaction; NBTC 403 likely unbpassable without a session.
This commit is contained in:
Kunthawat Greethong
2026-08-29 12:15:54 +07:00
parent 51400f20c7
commit 7f175e5a05
10 changed files with 216 additions and 20 deletions

View File

@@ -93,6 +93,23 @@ These are NOT quick plain-HTML collectors — they need a browser/XHR approach o
logged-in/authorized session. Do them as a separate effort if the analysis needs
them, not as simple additions to this collector family.
## Status updates (2026-08-29, follow-up asks)
- **Flexible scoring**: board no longer crashes on any single source failure —
`_fetch_with_cache` degrades (returns {} → theme drops that source; previous
good value kept as stale by the daily cache). Verified all-sources-down builds
13 themes.
- **Per-source calc detail**: `symbolDetail.factor_sources` shows, per theme, each
factor's source → raw → normalized → weight → contribution (audit trail for the
owner to tune weights). Also exposed in `/api/v1/dashboard` as `factor_sources`.
- **HAR feasibility (deferred sources)**: captured REIC via `har-derived-api-client`
(Playwright drove the JS SPA → HAR → derived XHR `POST /Home/Web_All_Num_View`).
Method WORKS and endpoint is derivable, but the homepage XHR returned an empty
body — real property data needs a deeper interaction (navigate to a Transfer
page and click to load its data). A full REIC collector is a larger follow-up,
not a quick add. NBTC's 403 is an IP/fingerprint anti-bot block that HAR replay
(plain HTTP) likely canNOT bypass — skip NBTC unless a session/credential exists.
---
## Task Breakdown