Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

All notable changes are recorded here. Versions follow [SemVer](https://semver.org/).

## v0.7.28 (2026-09-25)

自 v0.7.27 起累计 20 个 PR(#274–#293)。**无 schema 变更(仍 15)、无 config 变更**。本版主线仍是那条已被反复证实的规律:**一个事实只能有一个真源,显示口径必须等于消费口径** —— 本批把它推进到「**状态**」与「**边界**」两类载体上:越界的状态(跨身份、跨请求、跨渲染)与越界的口径(页 vs 数据集、控件 vs 查询)。

- **身份边界要收的不只是数据(#278 fa6c399 / #279 d640ef9)** — 登出只清缓存、隐藏 `#app`,而 `#help-panel` / `#chat-modal` / `#tour-overlay` 是 `#app` 的**兄弟节点**、交易视图的 `txTable.*` 与 `txRange`/`txCustomStart`/`txCustomEnd` 是**模块级**变量 ⇒ 上一会话的浮层留在登录页上被下一个人继承(设置视图开着帮助面板登出 ⇒ `#help-context` 仍印 `View: Settings`,而 `renderHelp()` 只在**打开**时渲染 ⇒ 永不自愈);交易页则载荷被清而**证据留下**,新会话按上一位的页码请求、服务端回 `items: []` 而「共 N 条」照旧印 3 条,且不自愈。修法都是**具名复位函数**(`resetSessionOverlays()` / `resetTxView()`,回到**声明处的默认值**)+ 边界一行调用;两轴各有门禁(浮层集与「收起」操作、名册三路派生)。被拒的竞争修法:只复位 `page`/清成 `undefined`(每页退化成 1 行)/在渲染里清证据(实测 300 次请求风暴)。
- **交易表:四张「说一套做一套」的脸一起收(#281 c448d31 / #282 abee8c3 / #284 e1cd51b / #285 54e0c65)** — ①一份 token 数量**三种拼写**(卡片 `Math.round(n/1000)+"K"`、行 `toFixed(1)`、CSV 导出写缩写文本),且卡片是那些行的合计 ⇒ 筛到只剩一行时同屏两个数不同写法;改为卡片**委派**同一函数、导出写**精确值**。②趋势图的**聚合粒度由控件决定**而不由实际请求窗口决定(`all` 与「自定义但两框都空」拼出逐字相同的无界请求,却分别要 `week`/`hour`)⇒ 同一窗口实测 **5 桶 vs 623 桶(124.6×)**;改为读请求串本身。③列头排序箭头说的是**整个数据集**,而 `buildDataTable` 只排**传进来的那一页**(请求从不带 `sort`、服务端硬编码 `ORDER BY t.id DESC`)⇒ 改为服务端**唯一白名单**(11 键,与前端 `TX_COLUMNS` 逐键相同)+恒尾 `, t.id DESC` 作分页锚 + 非法键/方向 **400**(校验先于取锁),前端只给列表请求带排序、签名覆盖排序(否则「箭头动而列表不动」比原缺陷更坏)。④分页器的省略号判据比它守的窗口**紧一格** ⇒ `page = 4` 与 `page = pages - 3` 两处**印出相邻页码却不放省略号**、一个真实页码消失(10 页时 `page 4` 显示 `1 3 4 5 … 10`);改为**由定义窗口的那行循环推导**(半宽 A=B=1 ⇒ 左 `page > A + 2`、右 `page < pages - (B + 1)`),门禁也写成推导式(接受任何自洽窗口,而不是把本次两个字面量钉死)。
- **缓存/载荷的「收据」必须由发起它的那次请求写(#289 9fd93ee)** — `loadTransactions()` 给刚加载的载荷盖三条收据,前两条取自**发请求前的快照**,第三条却在响应落地后读**活状态** ⇒ 印章与守卫的投影同源、比对**恒成立**:同一 RTT 内两次控件变更时,被取代的那份响应**不带身份**,它若最后落地就被采纳**并认证为当前** ⇒ 表格永久停在用户已经离开的筛选条件上、此后零请求。改为在 `await` **之前**捕获签名。
- **语言层与浮层/表单的收尾(#288 5e67055 / #293 25b9967 / #290 e081ffb)** — 切语言的重绘名册漏了**非模态**的快捷键面板(它不盖住设置页的语言下拉 ⇒ 用户能在它开着时切语言),而面板的四行快捷键与 `#help-context` 是 JS 建的、唯一调用点在**打开**分支 ⇒ 半翻译面板、整会话不自愈;登录按钮由 markup 声明 `login.enter`(「进入平台」),而提交处理器在 `finally` 里把它**恢复成别人的键** `T("login.submit")`(全仓唯一消费者)⇒ 输错一次密码按钮就改口,而登录页**没有语言切换器** ⇒ 整会话不自愈;忘记密码的成功提示用了一个样式表没声明的分级(`toast(..., "ok")`)—— `toast()` 不校验 `type`,没有 `.toast.ok` 规则的词**静默退回基类样式**。三处修法都只有一行级改动(补一次重绘 / 捕获 `origLabel` 回写并删掉那个键 / `"ok"`→`"success"`),但都补了门禁把「同一事实只有一个来源」钉住。
- **输入与展示的口径(#283 52aec72 / #287 118eea5 / #276 bd715f1 / #277 c6da6b8 / #291 1f1bd68 / #275 ed74e32 / #280 858c0b0)** — ①口令下限四处宣告「至少 8 **位**」,而服务端三处校验用的是 `String::len()`(UTF-8 **字节**)⇒ 实际下限约 2–3 个汉字(`密码abc` 5 字符 / 9 字节**被 API 接受**);客户端又用 `pw.length`(UTF-16 码元)⇒ `😀😀😀😀` 读 8 被表单放行。改为统一的按**字符**计数(Rust 逐标量、客户端 `Array.from`)。②忘记密码把「非空但太短」报成「请输入密码」——而应用早有 `err.weakPassword`(正是服务端同一规则经词表渲染出的那句);条件 ↔ 消息错配,改一个标识符。③市场页计数数的是**模型行数**却印成「N 个在售 key」(夹具 4 行 / 6 把 key ⇒ 屏幕写 "4 keys on sale");改名而非改数。④运营成员表的「余额」列只印**永久额**,而列头用的是全站给**可花额**(`balance + gift_balance`)的那组词 ⇒ 用户自己看 101、运营者看 100,差的正是那半「可花、会过期、真划走」的赠送额;改为与兄弟表(admin 成员)逐字同形。⑤交易类型筛选的散文只点名**一部分**被写入的类型(`expire` 缺席)⇒ 补全并由门禁钉住(名册从 SQL 常量渲染处派生)。⑥交易 CSV 导出的单元格转义器漏了 **CR**(记录分隔符正是 `\r\n`)⇒ 带裸 CR 的字段把**一条记录切成两条**;按 RFC 4180 §2.6 补进字符类。⑦上架表单的「每天」快捷勾选用 **property** 禁用七枚单日 chip,而成功后的回收走 `form.reset()` —— 它只还原值与勾选态、**不清 property** ⇒ 上架一次之后七枚 chip「未勾选 + 禁用」、点不动、整会话不自愈。
- **测试的声明 ≠ 它的输入(#274 7a078d8)** — SSE 分帧测试自称覆盖「跨块边界」,实际夹具把边界放在同一块内 ⇒ 补一条真正跨块的输入(仅测试,生产代码零改动)。

**新增门禁**(全部从被测算代码**派生**,不写快照):`the_identity_boundary_resets_the_transaction_view_state`、`the_identity_boundary_closes_the_panels_outside_the_app`、`the_transactions_view_states_one_token_quantity_one_way`、`the_trend_grain_derives_from_the_query_not_from_the_control`、`the_sort_indicator_and_the_order_by_share_one_source`、`the_pager_window_and_its_ellipsis_guards_agree`、`the_receipt_is_written_by_the_request_that_issued_it`、`the_escape_contract_reaches_every_dismissible_overlay`、`the_password_minimum_is_counted_in_the_unit_its_message_names`、`the_forgot_password_length_speaks_the_message_the_same_rule_gets_from_the_server`、`the_marketplace_count_is_expressed_in_the_unit_of_its_rows`、`the_ops_members_balance_cell_is_the_half_its_caption_names`、`every_toast_level_is_a_level_the_sheet_declares`、`a_form_control_disabled_by_the_property_is_cleared_on_the_recycle_path`、`the_language_switch_refreshes_every_overlay_it_can_show`、`the_control_that_rests_owns_its_label`、`the_csv_cell_escaper_quotes_every_rfc4180_special`。

**新增功能**:交易页趋势卡可在四档之间切换(**总点数(默认,窗口内累计净变化)** / 消费 / 收益 / 消费+收益)。四档**共用同一份载荷**(`trend` 接口本就返回 `net`/`income`/`expense`)⇒ 档位**不进**请求签名、不触发重拉;`net` 档用折线、y 域按带符号范围且含零基线、标题如实写口径(列筛选一加绝对余额不可定义);柱状三档的归一化/tooltip/图例**只按显示的系列**;复位在**视图入口**、不跨会话持久化(#292 c2f047d)。

`cargo test` 308 → **376**(新增 68 条门禁与回归测试)。前端资源令牌由各 PR 自行推格,本版最终为 `i18n.js` / `app.js` `?v=20260924-2`、`api.js` `?v=20260914-13`、`data.js` / `style.css` `?v=20260914-11`。

## v0.7.27 (2026-09-21)

自 v0.7.26 起 1 个 PR(#272)。本版修的是**同一族缺陷的第二次现身**:请求体上限分布在**两层**上、而两层是两个数。
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aitokenpool"
version = "0.7.27"
version = "0.7.28"
edition = "2021"
description = "AI Token 共享池 — 企业 key 池 + 公共共享市场"
license = "MIT"
Expand Down
Loading