diff --git a/BUGFIX_LOG.md b/BUGFIX_LOG.md index 0152ce4..c3d265b 100644 --- a/BUGFIX_LOG.md +++ b/BUGFIX_LOG.md @@ -9,6 +9,20 @@ --- ## 2026-08-11 +### BUG · 未评分职位卡被错误显示为 0 分 + +**错误** +切换 CV 后,大量没有当前 CV 精评分的缓存职位在列表中显示为 0 分,看起来像是模型给出了最低匹配结果。 + +**原因** +后端正确返回 `score: null`,但前端评分徽章先执行 `Number(null)`;JavaScript 会将其转换为数值 `0`,导致“未评分”和“真实 0 分”无法区分。 + +**解决方案** +评分徽章在数值转换前显式识别 `null` 和 `undefined`,未评分显示灰色长横线,真实数值 0 继续显示为 0。 + +**结果** +新增前端回归测试覆盖未评分与真实 0 分的区分;前端语法检查、Ruff、Python 编译和完整 pytest(248 tests)均通过。 + ### BUG · 已删除 Gmail 邮件导致增量同步游标永久停滞 **错误** diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f1505c..3a00813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Bug Fixes +- **Unassessed job cards no longer appear as zero-score matches** (`templates/index.html`) + Job cards whose current-CV score is `null` now show a gray em dash instead of being coerced to `0` by JavaScript. Genuine numeric zero scores still display as zero, preserving the distinction between "not assessed" and "assessed with no match". + - **Deleted Gmail messages no longer stall incremental sync** (`email_sync.py`) When Gmail history references a message that has already disappeared, a `messages.get` 404 is now treated as a terminal missing-message condition rather than a retryable fetch failure. The sync skips that message and saves Gmail's latest `historyId`, while authentication, rate-limit, server, and network errors still hold the cursor for a later retry. diff --git a/jobradar/templates/index.html b/jobradar/templates/index.html index e0149f5..90586bb 100644 --- a/jobradar/templates/index.html +++ b/jobradar/templates/index.html @@ -2095,8 +2095,9 @@

${display}`; } function normalizedScore(s) { diff --git a/tests/test_search_control.py b/tests/test_search_control.py index b99a81f..c8d89e2 100644 --- a/tests/test_search_control.py +++ b/tests/test_search_control.py @@ -94,3 +94,16 @@ def test_start_search_keeps_existing_jobs_until_sse_updates_them(): assert "JOBS = []" not in start_search assert "activeKey = null" not in start_search assert "if (existing >= 0) JOBS[existing] = job;" in html + + +def test_score_badge_distinguishes_unassessed_from_real_zero(): + html = (Path(__file__).parents[1] / "jobradar" / "templates" / "index.html").read_text( + encoding="utf-8" + ) + score_badge = html.split("function scoreBadge(s)", 1)[1].split( + "function normalizedScore", 1 + )[0] + + assert 'const missing = s === null || s === undefined;' in score_badge + assert 'const display = missing ? "—"' in score_badge + assert 'Number.isFinite(numeric) ? Math.round(numeric) : "?"' in score_badge