wshy
|
a90c12b3a5
|
Merge pull request #299 from kevin9327/fix/ext-data-rows-date-guard
fix(ext-data): rows 的 date 入参先校验再拼分区路径
|
2026-09-11 09:02:26 +08:00 |
|
wshy
|
fb7f7650d9
|
Merge pull request #298 from kevin9327/fix/market-time-non-trading-day-full-session
fix(market-time): 非交易日的已交易分钟数按全天算, 量比不再被折算放大
|
2026-09-11 09:02:22 +08:00 |
|
wshy
|
facf5f3c96
|
Merge pull request #297 from kevin9327/fix/backtest-json-nonfinite
fix(backtest): 信号回测统计里的 inf/NaN 不再让接口返回 500
|
2026-09-11 09:02:18 +08:00 |
|
wshy
|
8304175ffc
|
Merge pull request #296 from kevin9327/fix/trading-day-unknown-verdict-cache
fix(trading-day): 「未知」结论也按 TTL 缓存, 不再每拍重打探测
|
2026-09-11 09:02:15 +08:00 |
|
wshy
|
3625de9188
|
Merge pull request #295 from kevin9327/fix/limit-ladder-ext-timeseries-latest
fix(screener): 涨停梯队的时序扩展列只取最新分区, 不再放大行数
|
2026-09-11 09:02:11 +08:00 |
|
kevin9327
|
79eb150de2
|
fix(ext-data): rows 的 date 入参先校验再拼分区路径
`_read_ext_dataframe` 把 `date` 查询参数原样拼进 `timeseries/date=<值>`, 未经校验,
于是 `date=x/../../../../kline_daily` 读到的是 `ext_data/<id>/timeseries/` 之外的
`part.parquet` 并从 /rows 返回。同一文件的 /sync、/ingest、/backfill 都先
`date.fromisoformat` 再用, 只有这条读取路径没有。
拼路径前规范成 YYYY-MM-DD, 非法值按本文件既有约定返回 400。合法日期、
分区不存在、不传 date 三种情况的行为不变。
|
2026-09-11 00:50:33 +09:00 |
|
kevin9327
|
2b059d4b43
|
fix(market-time): 非交易日的已交易分钟数按全天算, 量比不再被折算放大
trading_minutes_elapsed_from_dt 的文档写明「非交易日(周末) = 240 (视作全天,
避免量比被折算成 0)」, 但实现里没有周几判断, 只按时刻分段。
compute_enriched_today 用 `time_factor = 240 / elapsed_minutes` 把盘中部分量
折算到全天量级。周末在行情页点「手动刷新」(refresh() 不过 _market_phase 门控)
且行情源不带 quote_ts 时, 兜底会走 trading_minutes_elapsed() ——
周六 9:31 得 1 分钟 → 全市场量比 ×240, 10:00 得 30 分钟 → ×8,
signal_volume_surge(量比 ≥ 2) 整片误触发。
补上文档已声明的周末判定。
|
2026-09-10 19:39:36 +09:00 |
|
kevin9327
|
e5f7f625fb
|
fix(backtest): 信号回测统计里的 inf/NaN 不再让接口返回 500
_json_safe 先命中 `isinstance(v, (int, float, str, bool))` 分支, 原生 float 的
inf/NaN 被原样放行; numpy 分支也只挡 NaN 不挡 inf。pf.stats() 经 pandas
Series.to_dict() 出来时 numpy 标量已装箱成原生 float, 所以清洗实际全部落空。
Starlette 的 JSONResponse 用 json.dumps(allow_nan=False) 渲染, 响应体里出现
一个 inf/NaN 就是整个 POST /api/backtest/run 500
(ValueError: Out of range float values are not JSON compliant)。全部交易都盈利时
Profit Factor = inf、零波动时 Sharpe = NaN 都会触发。
把非有限判定提到原生标量分支之前, 与 app/api/backtest._json_safe 同口径。
|
2026-09-10 19:38:33 +09:00 |
|
kevin9327
|
e956e3a6d7
|
fix(trading-day): 「未知」结论也按 TTL 缓存, 不再每拍重打探测
is_trading_day 的缓存命中条件带了 `_CACHE.verdict is not None`, 于是探测链
全部返回 None 时缓存永远读不回来, _TTL_UNKNOWN_S(300s) 形同虚设。
消费方 quote_service._holiday_gate 与 minute_refresh._gate_reason 在轮询循环里
每拍都调 is_trading_day: 未配 fuyao 且 tickflow 实时不可用/网络失败时, 每拍都会
重跑一遍探测链 (含一次 quotes.get 网络请求), 白白消耗限流额度并刷日志。
_CACHE.day 只在探测写回时设置, 「当天已探过」用它判定即可, 去掉多余的
verdict 判空条件。已有的 test_unknown_verdict_retries_after_short_ttl 仍然通过
(TTL 过期后照常重探)。
|
2026-09-10 19:36:30 +09:00 |
|
kevin9327
|
40c2468cbc
|
fix(screener): 涨停梯队的时序扩展列只取最新分区, 不再放大行数
ext_{config_id} 视图对 timeseries 模式覆盖 timeseries/**/*.parquet 全部分区
(app/api/ext_data._refresh_views), 一只票在 N 天快照里就有 N 行。梯队直接
LEFT JOIN 该视图, 同一只涨停股被复制 N 份, 各档 count 一并放大 N 倍。
改为与自选股列表 (app/api/watchlist) 同口径: 有配置时走 _read_ext_dataframe
取最新分区, 再按 symbol 去重后 JOIN; 无配置时保留视图查询兜底。
|
2026-09-10 19:35:32 +09:00 |
|
kevin9327
|
7755ab3a7d
|
fix(overview): 板块领涨股不再把 0.00% 当成缺失涨跌幅
_dimension_rank 用 `_finite(...) or -999` 作为排序键, 0.00% 是假值,
会被替换成 -999 排到所有下跌股之后。板块整体下跌、最强的一只恰好平盘时,
看板/复盘的「领涨」显示成跌幅最小的下跌股, 而不是那只平盘股。
改为显式区分 None 与 0.0 (缺涨跌幅 → -inf), 与 sector_monitor
_dimension_snapshot 的 `max(valid_rows, key=lambda row: row["change_pct"])`
同口径。
|
2026-09-10 19:32:13 +09:00 |
|
wshy
|
bb94cd7b29
|
Merge pull request #292 from kevin9327/fix/composite-single-candidate-neutral
fix(strategy): 叠加策略单候选子策略改用中性分, 与回测合并同口径
|
2026-09-10 09:10:50 +08:00 |
|
wshy
|
5c31616260
|
Merge pull request #291 from kevin9327/fix/ext-data-latest-sync-beijing-clock
fix(ext-data): 卡片「最新」时间按北京墙钟, 不再随服务端时区漂移
|
2026-09-10 09:10:47 +08:00 |
|
wshy
|
4ce7812565
|
Merge pull request #290 from kevin9327/fix/cold-limit-price-zero-guard
fix(indicators): 维表涨跌停价为 0 时不再把全部标的判成涨停
|
2026-09-10 09:10:43 +08:00 |
|
wshy
|
cd41bf54d3
|
Merge pull request #289 from kevin9327/fix/fundamental-matrix-stale-null
fix(backtest): 财务因子矩阵路径不再沿用上一期的过期值
|
2026-09-10 09:10:38 +08:00 |
|
wshy
|
a8f314df63
|
Merge pull request #288 from kevin9327/fix/optimizer-grid-step-overshoot
fix(optimizer): 参数网格按步长展开不再越过用户填写的上限
|
2026-09-10 09:10:34 +08:00 |
|
wshy
|
afb442f432
|
Merge pull request #287 from kevin9327/fix/kdj-zero-range-nan
fix(indicators): KDJ 零分母不再永久污染后续递推
|
2026-09-10 09:10:30 +08:00 |
|
wshy
|
87f185cdc3
|
Merge pull request #286 from kevin9327/fix/quote-interval-save-lock
fix(preferences): 轮询间隔写入走 save(), 不再覆盖并发写入的其它偏好
|
2026-09-10 09:10:27 +08:00 |
|
wshy
|
8f71cd8732
|
Merge pull request #285 from kevin9327/fix/rotation-prompt-index-pct-unit
fix(rotation): AI 轮动分析的大盘背景不再把指数涨跌幅放大 100 倍
|
2026-09-10 09:10:23 +08:00 |
|
wshy
|
c252cc328e
|
Merge pull request #284 from kevin9327/fix/limit-ladder-prev-trading-day
fix(screener): 涨停梯队按分区找前一交易日, 不再按固定自然日回看
|
2026-09-10 09:10:20 +08:00 |
|
kevin9327
|
5d0f1cba79
|
fix(indicators): 维表涨跌停价为 0 时不再把全部标的判成涨停
冷路径只校验了「非空且 < 哨兵」, 维表 limit_up 为 0 (数据源未提供该字段
的占位值) 会被当成权威涨停价, 使「raw_close >= 0 - 0.005」恒成立 —— 当日
所有标的进涨停名单、连板数一路累加; 跌停侧反过来永远判不出跌停。实时路径
_compute_limit_signals_today 已有 >0 守卫, 冷路径补齐同一守卫。
|
2026-09-10 08:21:06 +09:00 |
|
kevin9327
|
3f9c6da7dd
|
fix(ext-data): 卡片「最新」时间按北京墙钟, 不再随服务端时区漂移
扩展数据页同一张卡片上两个时间对不上: 底部「最新」显示 10:30:00, 而设置
里拉取面板的「上次」显示 18:30 —— 说的是同一次同步。Docker 镜像默认 UTC,
差的正好是一个时区。
latest_sync_date 由 parquet mtime 经 datetime.fromtimestamp(mtime) 格式化,
拿的是宿主机时钟, 且不带时区后缀; 前端 ExtDataStatCard 原样展示这串裸时间,
没有任何换算余地。旁边的 pull.last_run/next_run 是 datetime.now(timezone.utc)
的带偏移 ISO, 前端 new Date(iso) 按浏览器时区渲染, 所以那一侧是对的。
快照与时序两条路径都改成 fromtimestamp(mtime, tz=CN_TZ), 与
json_report_store._now_iso「用北京墙钟而非宿主机时钟」同口径。
展示格式不变。
|
2026-09-10 08:19:30 +09:00 |
|
kevin9327
|
0da6aea52a
|
fix(preferences): 轮询间隔写入走 save(), 不再覆盖并发写入的其它偏好
在设置里拖动「行情轮询间隔」的同时切换另一个开关(比如实时行情总开关),
刷新页面后那个开关又变回原样 —— 它被间隔的写盘整体覆盖掉了。
preferences.save 的 docstring 记着这个坑: "FastAPI 同步端点跑线程池,
并行 PUT 各自基于旧快照写盘会互相覆盖 (实测: 压缩总开关并行写分时/日K
两键, 后写者把先写者覆盖)", 所以它的 read-modify-write 整段在 _SAVE_LOCK
里。set_realtime_quote_interval 是唯一没跟上的 setter: 它自己 load() 拿快照,
再 _path().write_text() 全量写回, 全程不持锁。两个 PUT 在飞时, 后写的那份
旧快照会把先写的键抹掉。
改成 save({"realtime_quote_interval": interval}) —— 与本模块其余全部 setter
(set_sentiment_exclude_st / set_pipeline_pull_types / set_review_schedule ...)
一致, 返回值与缓存失效行为不变。
|
2026-09-10 08:13:24 +09:00 |
|
kevin9327
|
a714d70f83
|
fix(rotation): AI 轮动分析的大盘背景不再把指数涨跌幅放大 100 倍
「概念分析/行业分析 → AI 轮动分析」生成的报告里, 大盘部分写成「上证指数
上涨 123%」「深证成指下跌 45%」, 第 5 节「结合大盘」的结论也跟着跑偏。
_build_market_block 用 _fmt_pct 渲染指数涨跌幅, 而 _fmt_pct 是给概念/行业
涨幅(小数口径)写的, 会 *100。但 overview["indices"][].change_pct 是百分数
口径 (CONTRIBUTING §3.1): quote_service._build_index_quotes 的注释写明
"统一转成百分比输出", DB 兜底的 _index_quotes 同样 change_amount/pc*100。
于是 1.23 被渲染成 +123.00% 送进提示词。
新增 _fmt_index_pct 按百分数口径直接格式化, 与 market_recap._build_indices_block
(同一份 overview, 不 *100) 和 abnormal_moves._bench_rt_pct (消费前显式 /100)
的口径对齐; 概念/行业涨幅仍走原来的 _fmt_pct。
|
2026-09-10 08:04:48 +09:00 |
|
kevin9327
|
be54e11912
|
fix(strategy): 叠加策略单候选子策略改用中性分, 与回测合并同口径
子策略当天只选出一只票时无法排名, 选股合并却按 max(count-1,1) 把它当成
"最优=1", 凭空抬高该票的融合分; 回测合并 (merge_signal_matrices 的
n <= 1 分支) 用的是中性分 0.5。同一天同一标的在选股页和回测里评分与排序
不一致 —— 正是本模块声明要防的口径分裂 (_NEUTRAL_NORM 注释也写明单候选
应取中性分)。
|
2026-09-10 07:59:56 +09:00 |
|
kevin9327
|
5da887b737
|
fix(screener): 涨停梯队按分区找前一交易日, 不再按固定自然日回看
春节后第一个交易日打开「涨停梯队」, 断板(晋级失败)一栏是空的, 炸板股的
板数也从「昨日 N 板 + 1」退回 1 板。
load_prior_consecutive 在 as_of 前 1~9 个自然日里找 enriched 日分区。春节
长假连着调休周末, 相邻两个交易日能隔 10~11 个自然日 (如 2024-02-08 到
2024-02-19), 固定窗口整段落空, 函数返回空表, 上游把 prev_consec 整列填 0:
is_failed = ~is_limit & ~is_broken & (prev_c > 0) 恒假, boards 里的
prev_c + 1 也恒为 1。
改成枚举 enriched 的 date= 分区、由近到远取早于 as_of 的日期, 与
auction_benchmark._prev_trading_day「本地日K分区日期 = 已知交易日集合」
同口径; 回看分区数上限保持 10, 缺列继续往前找的行为不变。
|
2026-09-10 07:53:07 +09:00 |
|
kevin9327
|
03f8966856
|
fix(backtest): 财务因子矩阵路径不再沿用上一期的过期值
矩阵侧逐列前向填充时跳过空值写入, 新一期财报缺某指标就继续沿用上一期,
同一行会混用两期报告 (pb 取新期净资产、roe 停在上一期); polars 侧
join_asof 只认最新一期整行, 该指标为 null。同一份配置两条路径给出不同
因子值。改为空值同样覆盖为 NaN, 与 attach_fundamental_factors 口径一致。
|
2026-09-10 07:50:04 +09:00 |
|
kevin9327
|
72a0f51a64
|
fix(optimizer): 参数网格按步长展开不再越过用户填写的上限
(max-min) 不是 step 整数倍时, round() 算步数会向上取整多造一个候选:
「1~20 步长 7」展开成 [1,8,15,22], 22 再被参数自身的 range 校验拒绝,
用户填的正是参数合法上限却直接报错;「0.01~0.05 步长 0.015」则静默
多扫一个 0.055。步数改为向下取整 (保留 1e-9 容差, 整除区间端点不丢)。
|
2026-09-10 07:47:00 +09:00 |
|
kevin9327
|
1e2c7afa93
|
fix(rps): 轮动矩阵缓存按覆盖天数复用, 切到更长窗口不再少列
打开「概念分析 → 涨幅RPS轮动」时先看 7 日再切到 30 日, 矩阵只有 25 列。
build_rps_rotation 按 days 换算日历窗口读 enriched (days=7 只读 24 个自然日),
但结果缓存键是 "{kind}|{level}|{latest}", 不含 days。120s TTL 内第二次请求
命中第一次那份按 7 日窗口算出来的矩阵, _slice_cached 又因为 len(dates) <= days
原样返回, 于是请求 30 列拿到 25 列。
记录每个缓存条目实际覆盖的天数, 只在覆盖天数 >= 请求天数时复用; 反方向
(宽窗缓存服务窄请求) 仍按原样 slice 复用。
|
2026-09-10 07:45:55 +09:00 |
|
kevin9327
|
cc48d51c20
|
fix(indicators): KDJ 零分母不再永久污染后续递推
9 日内最高价=最低价时 RSV 分母为 0 (不是空值), 原 fill_null(1e-12)
守卫不生效, 0/0 得到 NaN 后被 ewm_mean 递推永久传染, 该标的此后
所有交易日 KDJ 都是 NaN。改为零分母置空并让 EWM 跳过空值继续递推,
与 backtest/matrix 的矩阵路径口径一致。
|
2026-09-10 07:42:28 +09:00 |
|
shy3130
|
d0a14b5c1b
|
fix(ext-pull): 拉取循环的状态回写不再清策略缓存
上修复 (keep_strategy_cache 沿数据写入链放行) 后线上复现: 每轮拉取
成功后 12ms 缓存仍被清空。clear_cache 新增调用链日志抓到真凶 —
ExtConfigStore.upsert 无条件触发 _invalidate_ext_derived: 调度器每轮
拉取要回写 last_run/last_status/next_run 共 2-3 次配置, 每次都全清
策略结果缓存, 绕过了已放行的数据写入链路。
upsert 增加 keep_strategy_cache 参数 (默认 False 保持 UI 保存配置/
手动变更的全清语义), 拉取循环内 4 处例行回写全部传 True。
|
2026-09-09 16:30:20 +08:00 |
|
shy3130
|
71cec0dc35
|
ops(strategy): clear_cache 记录调用链日志
策略页依赖 strategy_cache 秒加载, 缓存被清空即整页回退到全量重算。
今日线上排查: 缓存在扩展表拉取后 12ms 消失, 但三个已知调用方均无
触发记录, 静态分析无法定位。clear_cache 打 WARNING 附最近 5 帧调用
链, 此类问题不再依赖复现现场。
|
2026-09-09 16:10:03 +08:00 |
|
shy3130
|
6345eb93ab
|
fix(strategy): 渐进式 run_all 逐策略隔离失败
单个策略执行崩溃 (如自定义策略 filter_history 的数据类型错误) 会杀掉
整批剩余策略: handle 整体 fail, 后台线程结束, 页面剩余卡片永远不亮。
线上实证: 70 策略池跑到第 35 个 (custom_1782999589 pl.DataFrame 构造
schema 混杂) 崩溃, 后 36 个全部没算。
改为单策略 try/except: 失败记入 handle.errors 并移出待算队列, 其余
策略照常算完落缓存; 响应新增 errors 字段 (前端可忽略)。job 级失败
(context 构建崩溃) 仍走整体 500 语义不变。
|
2026-09-09 15:49:21 +08:00 |
|
shy3130
|
01347b72bc
|
perf(strategy): 渐进式 run_all 只构建一次共享矩阵
_run_all_progressive 逐策略调用 engine.run_all(strategy_ids=[sid]),
run_all 不回写 context.market → 每个 matrix_native 策略都重建一次
全市场矩阵 (39 万行, 小服务器单次数秒到十余秒), 6 策略一轮多耗约
1 分钟。
从 run_all 抽出 build_shared_matrix (字段并集语义不变, 非渐进路径
行为一致), 渐进式循环外一次建好放入 context.market 复用。
|
2026-09-09 15:30:10 +08:00 |
|
shy3130
|
b531475ca8
|
fix(ext-pull): 定时拉取不再清空策略结果缓存
扩展表 PullScheduler 每轮成功写入都会经 invalidate_ext_caches 销毁
strategy_cache, 策略页随之下一次轮询整页空白, 且前端会话级防重入
(runAllDateRef) 不会自动补跑, 小服务器上全量重算需分钟级 → 页面长期黑屏。
例行数据刷新改为只失效扩展帧缓存与注册同步状态 (下次策略运行自然
读到新值); 手动上传/配置变更保持全清 (触发下次全量重算) 旧行为。
keep_strategy_cache 沿 fetch_and_ingest → rows_to_parquet →
write_ext_parquet → invalidate_ext_caches 显式传递。
|
2026-09-09 15:30:10 +08:00 |
|
shy3130
|
8d8b66c7f8
|
fix(kline): 分钟批量补全识别前部空洞, 重启跨开盘后分时可自愈
盘中重启/停机跨开盘后, 本地当日分钟K只剩重启时刻起的连续尾巴。
缺口判定只检查相邻K间隔, 连续尾巴被判"仅尾部落后"走增量 — 增量
锚定本地最新时间, 永远不会回看缺的开头, 上午的洞永久残留, 自选
分时只显示几根K。
- _has_holes 增加前部洞判定: 当日首根 > 开盘+6min 容差即视为洞,
归入全天重拉 (取到即落盘, 一次自愈)。仅根数不足的分支才判定,
稳态零额外请求; 停牌晚开票命中亦幂等无害
- 全量分钟服务健康时不再压制空洞类补拉 (服务增量补不了洞),
纯尾部落后的压制维持不变
实测: 服务器重启窗口后策略页(本地为空)走全天拉取显示完整、
自选页(有连续尾巴)被增量锁死只显示 11 根, 修复后统一自愈。
|
2026-09-09 12:13:04 +08:00 |
|
wshy
|
3db7f38446
|
Merge pull request #281 from 0112020179/codex/fix-enriched-refresh-memory
fix(oom): 降低补算内存峰值并统一重任务并发控制
|
2026-09-09 11:36:22 +08:00 |
|
0112020179
|
771a95a6d1
|
fix(oom): 降低补算内存峰值并统一重任务并发控制
|
2026-09-09 11:09:48 +08:00 |
|
wshy
|
5ffe43d42d
|
Merge pull request #280 from kevin9327/fix/backtest-stream-date-400
fix(backtest): SSE 端点非法 start/end 返回 400 而不是 500
|
2026-09-09 09:04:52 +08:00 |
|
wshy
|
efd9f820d4
|
Merge pull request #279 from kevin9327/fix/screener-run-all-as-of
fix(screener): run_all 的 as_of 与 /custom、/preset 同口径校验 (数字 as_of 会写坏策略缓存)
|
2026-09-09 09:04:46 +08:00 |
|
wshy
|
6eb1508fd8
|
Merge pull request #278 from kevin9327/fix/alerts-query-bounds
fix(alerts): 触发记录查询的 days/limit 补上范围约束 (limit=-1 静默丢记录)
|
2026-09-09 09:04:40 +08:00 |
|
wshy
|
7dc11125bf
|
Merge pull request #277 from kevin9327/fix/merge-history-null-announce-date
fix(financial): 公告日为空的旧行不再压过带公告日的新行
|
2026-09-09 09:04:35 +08:00 |
|
wshy
|
7e99a07270
|
Merge pull request #276 from kevin9327/fix/quotes-flush-quote-ts
fix(kline): 实时行情覆写当日日K分区时补写 quote_ts
|
2026-09-09 09:04:28 +08:00 |
|
wshy
|
fe1410532f
|
Merge pull request #275 from kevin9327/fix/factor-delete-fail-closed
fix(factors): 删除因子被拒绝时定义已被删掉 (删除路径未 fail-closed)
|
2026-09-09 09:04:22 +08:00 |
|
wshy
|
5467b0dca4
|
Merge pull request #274 from kevin9327/fix/fundamental-announce-day-hole
fix(fundamentals): 换报告期公告当日不再丢失上一期财务因子值 (与矩阵路径口径对齐)
|
2026-09-09 09:04:17 +08:00 |
|
wshy
|
464a5d9d50
|
Merge pull request #273 from kevin9327/fix/test-endpoint-cold-cache
fix(settings): 端点清单缓存未预热时端点测速 500
|
2026-09-09 09:04:11 +08:00 |
|
wshy
|
99f478b257
|
Merge pull request #272 from kevin9327/fix/report-created-at-beijing-time
fix(reports): AI 报告 created_at 改用北京墙钟, 修复 UTC 部署下「8 小时前」
|
2026-09-09 09:04:05 +08:00 |
|
wshy
|
970296e82e
|
Merge pull request #271 from kevin9327/fix/minute-sync-beijing-window
fix(kline): 分钟K增量同步窗口统一按北京时区
|
2026-09-09 09:04:00 +08:00 |
|
wshy
|
eebe533986
|
Merge pull request #270 from kevin9327/fix/rotation-signal-date-alignment
fix(rotation): 轮动信号缺失日按日期归位补齐, 新晋概念不再被误判为退潮
|
2026-09-09 09:03:54 +08:00 |
|
 kevin9327andClaude Opus 5
|
68005c92e6
|
fix(alerts): 触发记录查询的 days/limit 补上范围约束
GET /api/alerts 的 days、limit 是裸 int,没有任何约束,越界值不报错而是
静默返回错误结果:
- days=-1 → cutoff 被推到未来,200 但 alerts 为空(total 仍是 3)
- limit=-1 → out[:limit] 变成负数切片,3 条记录只返回 2 条,
静默丢掉最旧一条,调用方无从察觉
- limit=0 → 200 但 alerts 为空
同类列表端点已有正确写法:abnormal.py 用 `limit: int = Query(500, ge=1,
le=2000)`,rps.py 用 `days: int = Query(12, ge=7, le=30)`,越界直接 422。
本次把 /api/alerts 补齐到同一口径,上下限取存储侧保留策略本身
(alert_store.MAX_DAYS / MAX_RECORDS),不新增常量,超出保留窗口的请求
本来也没有可返回的数据。
前端 alertsList 实际只传 days=7、limit=1/10/500,全部落在新区间内;
新增的 tests/test_alerts_query_bounds.py 同时锁住这些合法取值仍返回 200
且记录条数不变。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-09 07:37:17 +09:00 |
|