移除日历视图:功能与决策卡重叠,维护成本高于价值

- 删除 CalendarView.tsx、calendar-action-utils.ts 及其测试文件
- 删除 ScanTerminalCalendar.module.css
- ScanTerminalDashboard:移除日历 tab 按钮、日历渲染分支、ContentView 类型中的 calendar
- ScanTerminalLightTheme:清理所有 .scan-calendar-* 规则(~40 行)
- scan-root-styles.ts:移除 ScanTerminalCalendar 导入

同时完善地理排序:
- scan_terminal_filters.py:market_region_from_tz_offset 细化为 7 个区域(东亚/东南亚/中亚/西亚/欧洲非洲/南美/北美)并增加 sort_order
- scan_terminal_city_row.py:传递 trading_region_sort
- dashboard-types.ts:增加 trading_region_sort 字段
- decision-utils.ts:sortRowsByUserTime 按 trading_region_sort 优先排序

Rejected: keep-calendar-view, calendar-actions-overlap-with-decision-cards
Tested: npx tsc --noEmit, python -m ruff check .
This commit is contained in:
2569718930@qq.com
2026-05-10 15:48:18 +08:00
parent 5ff9fade5f
commit 9635387beb
11 changed files with 28 additions and 1054 deletions
@@ -1,81 +0,0 @@
import assert from "node:assert/strict";
import {
buildCalendarCoreReason,
buildCalendarMeta,
getCalendarActionGroup,
} from "@/components/dashboard/scan-terminal/calendar-action-utils";
import type { ScanOpportunityRow } from "@/lib/dashboard-types";
function row(overrides: Partial<ScanOpportunityRow>): ScanOpportunityRow {
return {
city: "London",
city_display_name: "London",
current_temp: 21,
deb_prediction: 24,
id: "london-2026-04-27",
local_date: "2026-04-27",
local_time: "4/27·00:01",
selected_date: "2026-04-27",
temp_symbol: "°C",
...overrides,
} as ScanOpportunityRow;
}
export function runTests() {
const snapshotMs = Date.UTC(2026, 3, 27, 16, 1);
const sameNow = snapshotMs;
const localTimeCase = row({
minutes_until_peak_end: 119,
minutes_until_peak_start: 0,
window_phase: "active_peak",
});
const meta = buildCalendarMeta(localTimeCase, "zh-CN", snapshotMs, sameNow);
assert.equal(meta.startAtMs, snapshotMs);
assert.ok(meta.localWindowLabel, "should expose the user's local peak window");
assert.notEqual(meta.localWindowLabel, localTimeCase.local_time);
assert.doesNotMatch(meta.localWindowLabel || "", /4\/27·00:01/);
const activeGroup = getCalendarActionGroup(localTimeCase, meta, sameNow, "zh-CN");
assert.equal(activeGroup.key, "now");
const breakoutReason = buildCalendarCoreReason(
row({
cluster_core_high: 24.7,
cluster_core_low: 23.1,
cluster_model_count: 6,
current_temp: 25.2,
model_cluster_sources: {
ecmwf: 24.4,
gfs: 24.7,
},
}),
activeGroup,
"zh-CN",
);
assert.match(breakoutReason, /实测已高于模型上沿/);
assert.doesNotMatch(breakoutReason, /等待下一报文确认方向/);
const pastMeta = buildCalendarMeta(
row({
minutes_until_peak_end: -20,
minutes_until_peak_start: -120,
window_phase: "post_peak",
}),
"zh-CN",
snapshotMs,
sameNow,
);
const pastGroup = getCalendarActionGroup(
row({ minutes_until_peak_end: -20, minutes_until_peak_start: -120, window_phase: "post_peak" }),
pastMeta,
sameNow,
"zh-CN",
);
assert.equal(pastGroup.key, "past");
assert.match(
buildCalendarCoreReason(row({}), pastGroup, "zh-CN"),
/峰值窗口已过,若无新高应避免追高/,
);
}