后台表查询枚举列按 schema 展示变体名,不再只看数值
- 新增按 SpacetimeDB schema 解析枚举展示名的实现:读取 typespace.types 与表的 product_type_ref,为每个「Sum 且变体全为单元变体」的列建立按变体索引排列的展示名,变体名归一到 snake_case - 支持 Option<枚举> 列:标记 optional,[0, [索引, []]] 出变体名、[1, []] 仍是空值;Option<普通值> 与带载荷的 Sum 继续走通用解码,单变体枚举同样出名字 - 删除只覆盖 profile_recharge_order.kind / status 的硬编码映射 normalize_admin_database_known_enum - 枚举展示名同时作用于行的 cells 与 raw,关键词搜索、结构化筛选和稳定排序都按展示名生效 - 表查询行解析与行构建改为接收枚举映射,schema 夹具用例覆盖直接枚举、Option 枚举、单变体枚举与未知表 - 同步开发运维文档的表查询口径段、后台 skill 的 SATS 展示参考与决策记录 - 验证:cargo test -p api-server --manifest-path server-rs/Cargo.toml --bin api-server admin(139 passed / 0 failed / 1 ignored);cargo check -p api-server;cargo fmt --all --check;npm run check:encoding;npm run check:doc-index;git diff --check;本地 dev schema 回放同一算法,85 张表 32 个直接枚举列 + 2 个 Option 枚举列全部解析出展示名、0 残留
This commit is contained in:
+11
@@ -41,3 +41,14 @@
|
||||
## 注意
|
||||
|
||||
不同 enum 的 variant 顺序必须以生成 binding 或 module 源码为准,不能复用其他 enum 的索引映射。
|
||||
|
||||
## 通用表查询页的枚举展示(2026-09-23 起)
|
||||
|
||||
后台“表查询”(`#tables`)不再逐表硬编码枚举映射,改为按 schema 自动解析:
|
||||
|
||||
- api-server 在 `server-rs/crates/api-server/src/admin.rs` 读取 schema 的 `typespace.types` 和表的 `product_type_ref`,对每个“`Sum` 且所有变体都是单元变体(`Product.elements` 为空)”的列生成 `列名 -> [按变体索引排列的展示名]`,变体名归一到 snake_case。
|
||||
- `Option<枚举>` 列单独标记为可空:`[0, [索引, []]]` 出变体名,`[1, []]` 仍是空值。`Option<普通值>` 与带载荷的 Sum 直接跳过,交回通用解码,避免把普通 `Option` 列误标成枚举名。
|
||||
- 映射同时应用到 `cells` 与 `raw`,因此关键词搜索、结构化筛选、稳定排序解析到的都是展示名。
|
||||
- 单变体枚举也要出名字;变体索引顺序以 schema 为准,不依赖生成 binding 的副本。
|
||||
|
||||
因此新增表或新增枚举列无需再改后端映射,只要模块已发布且 schema 可读;如果 schema 读取失败,表查询会以“表不存在”失败,而不是退回展示数字。定向验证:`cargo test -p api-server --manifest-path server-rs/Cargo.toml --bin api-server admin_database`。
|
||||
|
||||
@@ -9299,3 +9299,12 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 影响范围:`server-rs/crates/api-server/src/{admin.rs,admin_recharge.rs}`、`server-rs/crates/shared-contracts/src/admin.rs`、`apps/admin-web/src/api/adminApiTypes.ts`、`apps/admin-web/src/pages/{AdminRechargeOrderPage.tsx,AdminRedeemCodePage.tsx}`、`apps/admin-web/src/components/AdminUserDetailDialog.tsx`、对应三个用例文件与后端架构数据契约文档。
|
||||
- 验证方式:`cargo test -p api-server --manifest-path server-rs/Cargo.toml --bin api-server cumulative_recharge`(2 条新用例)与 `cargo check -p api-server`;`npm run admin-web:typecheck`;`npx vitest run apps/admin-web/src`(220 passed),其中三个定向文件 33 passed(新增「未支付订单不显示实付金额,发放泥点单独成列」与「累计充值读取不到时展示未知,不用订单列表近似」)。
|
||||
- 边界(未验证):未连真实生产库核对历史订单的累计充值数值,也未跑真实栈 API smoke。
|
||||
|
||||
## 2026-09-23 后台表查询枚举列按 schema 展示变体名,不再只看数值
|
||||
|
||||
- 背景:后台「表查询」页的枚举列直接落回通用解码,只有 `profile_recharge_order` 的 `kind` / `status` 做了硬编码映射,其余 20 多张表的枚举列(如 `profile_wallet_ledger.source_type`、`tracking_event.scope_kind`、`profile_membership.tier`)都显示成 SATS 原始数值,运营在后台看不到枚举值。
|
||||
- 决策(按 schema 自动解析):api-server 在 `server-rs/crates/api-server/src/admin.rs` 读取 SpacetimeDB schema 的 `typespace.types` 与表的 `product_type_ref`,对每个「`Sum` 且所有变体都是单元变体」的列生成「列名 → 按变体索引排列的展示名」;变体名归一到 snake_case,与后台既有枚举字符串(`points` / `paid` / `asset_operation_consume`)同口径,因此原硬编码映射的展示结果不变,新增表与新增枚举列不再需要改代码。
|
||||
- 决策(边界):`Option<枚举>` 列单独标记为可空(`[0, [索引, []]]` 出变体名、`[1, []]` 仍是空值),`Option<普通值>` 与带载荷的 Sum 不参与映射,继续走通用解码(`Some` 解包、`None` 归空、时间戳原样透出);单变体枚举同样要出名字。映射同时作用于 `cells` 与 `raw`,关键词搜索、结构化筛选和稳定排序都按展示名生效。schema 读取失败时表查询以「表不存在」失败,不会退回展示数字。
|
||||
- 影响范围:`server-rs/crates/api-server/src/admin.rs`(新增 schema 解析与 `build_admin_database_enum_labels`,删除 `normalize_admin_database_known_enum`,`parse_admin_database_table_rows_sql_response` / 行构建与归一化改为接收枚举映射)、`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`、`.codex/skills/genarrative-admin-backoffice/references/spacetimedb-http-sql-sats-display.md`。前端与 DTO 不变。
|
||||
- 验证方式:`cargo test -p api-server --manifest-path server-rs/Cargo.toml --bin api-server admin::tests`(86 passed,含新增 `admin_database_enum_labels_come_from_schema_variants` 与改写后的充值订单枚举用例);用本地 dev schema 逐表回放同一算法,85 张表里 32 个枚举列全部解析出展示名、0 个残留;`cargo check -p api-server`、`cargo fmt --all --check`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check` 通过。
|
||||
- 边界(未验证):没有对真实 HTTP 表查询响应做端到端比对(本地 dev api-server 仍是改动前二进制,未重启)。
|
||||
|
||||
@@ -1112,7 +1112,7 @@ SELECT * FROM profile_recharge_order WHERE status = 'expired' AND expiration_che
|
||||
SELECT * FROM profile_recharge_product_config ORDER BY sort_order ASC;
|
||||
```
|
||||
|
||||
后台通用表查询已经处理 SpacetimeDB 无载荷枚举的 SATS 形态。新增后台表展示时,枚举列优先按表名和列名做业务映射,再落回通用解码。
|
||||
后台通用表查询按 SpacetimeDB schema 自动处理无载荷枚举的 SATS 形态:api-server 读取 schema 的 typespace 与表的 `product_type_ref`,为每个“`Sum` 且变体全为单元变体(排除 `Option` 的 `some` / `none`)”的列建立按变体索引排列的展示名,变体名归一到 snake_case,与 `points` / `paid` / `asset_operation_consume` 等同口径;`Option<枚举>` 列单独标记为可空,`[0, [索引, []]]` 出变体名、`[1, []]` 仍是空值。该映射同时作用于行的 `cells` 和 `raw`,所以关键词搜索、字段筛选与排序都按展示名生效;`Option<普通值>`、带载荷的 Sum 和非枚举列继续走通用解码(`Some` 解包、`None` 归空、时间戳按原样透出)。新增表或新增枚举列不再需要改代码,前提是模块已发布且 schema 可读;schema 读取失败时表查询本身就以“表不存在”失败,不会退回按索引展示数字。
|
||||
|
||||
后台通用表查询的“每页条数”不是筛选前的 SQL 截断量。API Server 通过单次 `SELECT * ... LIMIT 50001` 读取哨兵行,最多保留前 50,000 条候选;关键词 / 字段条件过滤、所选列的完整候选集稳定排序和 1-based `page` 分页都基于这一次 SQL 结果,`totalMatched` 不再依赖另一份 `COUNT(*)` 快照。`filters` 支持两种 JSON 形式:object(列名到等值,如 `{"user_id":"u1"}`,兼容旧入口)与条件数组(如 `[{"column":"points","op":"gt","value":"5"}]`,运算符覆盖 `eq`、`ne`、`gt`、`gte`、`lt`、`lte`、`contains`、`notContains`、`startsWith`、`endsWith`、`in`、`notIn`、`isEmpty`、`isNotEmpty`,允许同列多条件,条件间为 AND);两种形式的用户输入都不进入 SQL,只在 API Server 内存中过滤。请求页码超过实际总页数时钳制到末页,零结果固定返回第 1 页。存在第 50,001 条哨兵行时响应必须返回 `scanLimitReached=true`,后台固定分页栏上方明确提示匹配总数和分页结果可能不完整,不得把扫描范围外的数据误报为不存在。候选 SQL 响应体仍受 32 MiB 和 20 秒硬限制;宽表即使每页条数很小也可能整次拒绝,不会返回部分结果。实时写入仍可能改变相邻请求的候选快照,精确审计应使用对应业务表的专用查询而不是通用浏览页。
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user