Commit Graph

5991 Commits

Author SHA1 Message Date
k88936 8788c47a97 修复(AGC模型): 锁定模型项不再进入 Tab 序列
- 去掉锁定项的 tabIndex,原因改由 aria-label 与 hover 提示暴露,避免键盘停在不可选项
- 移除锁定项失效的 :focus-visible 样式与旧注释
- 更新单测:断言锁定项不可 Tab 聚焦且 aria-label 带原因
2026-10-05 18:59:57 +08:00
k88936 e90929057c 修复(会员补差): ceil_div 零分母不再静默返回 0
- 删除 denominator == 0 时的静默 0 元兜底,保留 debug_assert 并在 release 下除零 panic
- 与函数注释「零分母属程序员错误,应立刻暴露」保持一致,避免潜在少收金额
2026-10-05 18:15:36 +08:00
k88936 b8309eb3ae 重构(后台金额): 抽出统一的元金额格式化
- shared AdminFormat 新增 formatAdminCurrencyCents(分 → ¥x.xx)并从 components 导出
- AdminUserDetailDialog / AdminMembershipPlanPage / AdminRechargeOrderPage / AdminRechargeProductPage 删除各自重复的 formatMoney/formatPrice
- 补充 formatAdminCurrencyCents 单测,避免后台各页面金额格式漂移
2026-10-05 18:12:22 +08:00
k88936 87a3794423 文档(会员契约): 后台改档请求并发上限不再硬编码 128
- AdminUpsertProfileMembershipPlanRequest.concurrentJobLimit 改为引用后端下发的 unlimitedConcurrencyThreshold
- 同步重新生成 ts-rs 绑定
2026-10-05 17:56:02 +08:00
k88936 8e9d2389e0 文档(会员契约): 并发上限不再硬编码 128 哨兵
- ProfileMembershipPlanResponse.concurrentJobLimit 改为引用后端下发的 unlimitedConcurrencyThreshold
- 同步重新生成 ts-rs 绑定,避免哨兵值变更时注释误导消费方
2026-10-05 17:54:38 +08:00
k88936 759bcf98a8 文档(会员契约): 澄清 status 兜底只作用于 Rust 客户端
- ProfileMembershipResponse.status 注释改为“Rust 反序列化未知取值按 active 兜底,TS 侧不归一化”
- 同步重新生成 ts-rs 绑定,避免 Web 消费方误以为前端也会 fail-open
2026-10-05 17:53:23 +08:00
k88936 8009a70bb1 测试(AGC模型): 目录透传用例去掉过期的映射断言
- loadClientLlmModels 已改为直接透传 Rust typed command 结果
- 用例改名为透传断言,不再期望渲染层补默认 agentMode(该逻辑已下沉到 Rust)
2026-10-05 17:42:46 +08:00
k88936 8ed716c6e2 修复(充值弹层): 任一商品提交中即禁用会员结算
- 会员结算 canSubmit 由 !submitting 改为 !submittingProductId,与充点分支的 ctaDisabled 口径一致
- 避免充点在途时仍能提交会员结算、被 buyRechargeProduct 静默丢弃后直接关闭弹层
- 补充反向用例:泥点订单提交中时会员结算按钮禁用
2026-10-05 17:41:26 +08:00
k88936 7dc056651c 修复(后台用户详情): 非会员不展示占位账期
- 账期仅在 membership.status === 'active' 时展示,否则显示 -
- 避免从未订阅用户显示“月付 第 1/1 期”被误读为正在计费
2026-10-05 17:38:01 +08:00
k88936 07cf7443da 重构(后台契约): 会员变更类型复用后端生成 token
- AdminMembershipOrderChangePayload.changeKind 改用 ProfileMembershipChangeKindToken
- 去掉手写的 'purchase' | 'upgrade' 联合,避免与后端 token 漂移
2026-10-05 17:37:12 +08:00
k88936 9707b74002 修复(后台会员档位): 列表加载时按 rank 排序
- refreshPlans 复用 sortPlanEntries,首屏顺序与保存后一致
- 避免加载态与保存态列表顺序不一致,与档位列“按升级基准 rank”的说明对齐
2026-10-05 17:35:18 +08:00
k88936 92a8fa1b66 重构(共享导出): 会员商品 id helper 提升为公共导出
- packages/shared/src/index.ts 导出 resolveMembershipProductId
- useAccountWallet 改从 @genarrative/shared 公共入口引入,去掉对弹层私有文件结构的深路径依赖
2026-10-05 17:34:27 +08:00
k88936 ff1e15194d 重构(泥点钱包): 去掉冗余的余额视图联合成员
- PlatformMudPointWalletEntryProps.breakdown 收敛为 ProfileMudPointBalance | null
- ProfileMudPointBalanceView 是 ProfileMudPointBalance 的扩展,联合会被 TypeScript 折叠,属于多余类型噪音
- 同步删除不再需要的 type-only import
2026-10-05 17:34:03 +08:00
k88936 715a4992fd 修复(后台假接口): 会员档位夹具补齐 recommended 字段
- membership-plans 的 GET 列表与 POST 回显补上契约必填的 recommended
- 按后端 PROFILE_MEMBERSHIP_RECOMMENDED_PLAN 把 plus 标为推荐,避免本地预览与真实响应漂移
2026-10-05 17:30:55 +08:00
k88936 2ac445fe11 修复(后台假接口): 用户详情钱包夹具对齐 AdminProfileWalletPayload
- userDetail.wallet 去掉已删除的 balance 字段,补齐 totalBalance/dailyFreePoints/monthlyPoints/refundDebtPoints/userId
- 与 recharge-orders 路由的 wallet helper、AdminUserDetailDialog 的读取字段保持一致,避免本地预览显示 undefined
2026-10-05 17:30:18 +08:00
k88936 cebffb9dad 测试(AGC模型): 补齐裸目录响应兼容用例
- 新增 legacy_raw_catalog_payload_defaults_optional_fields:覆盖无 ok 信封、缺少 agentMode/protocol/unavailableModels 的旧裸目录响应
- 断言缺省按 Codex + OpenAI Responses + 空不可用桶兜底,锁定既有兼容行为
2026-10-05 17:28:38 +08:00
k88936 bc3e36ff33 重构(会员契约): 会员结构体改用 ts-rs 生成类型
- shared-contracts 为 10 个会员结构体补 ts_rs::TS / ts(export),64 位整数字段补 ts(type = "number") 对齐前端 number
- 新增 10 个生成绑定;packages/shared 与 admin-web 改为 re-export 生成类型,仅 kind / status 等前端收窄联合用 Omit 组合保留
- 同步设计文档 §2.5 与决策日志
2026-10-05 15:51:07 +08:00
k88936 0930e402be 修复(会员错误码): 修正 ProductIdUnparseable 拼写
- module-runtime 变体 ProductIdUnparsable 改名为 ProductIdUnparseable,wire 串 product_id_unparsable 同步改为 product_id_unparseable(本 PR 未上线,不留兼容)
- 同步 spacetime-module 拒绝点、spacetime-client mapper 与 api-server 测试引用,并重新生成 SpacetimeDB 绑定
- 同步设计文档 §5.8 与决策日志
2026-10-05 15:32:19 +08:00
k88936 42c4cacf72 修复(会员契约): 响应 token 反序列化前向兼容
- shared-contracts 为会员响应 DTO 的 plan / status / cycle_kind / model_access 字段加 deserialize_with,未知取值 fail-open 兜底到已知最高档,避免 AGC Tauri shell 等旧 Rust 客户端因后端新增 token 整包解析失败
- 入参 DTO 保持严格拒绝,不改枚举自身 Deserialize,避免 Unknown 变体污染入参
- 补响应兼容与入参严格测试;同步设计文档 §2.5 与决策日志
2026-10-05 15:11:47 +08:00
k88936 c85da3a983 修复(AGC模型): 档位无可用模型改用独立错误码
- module-runtime 新增 MODEL_UNAVAILABLE / MODEL_UNAVAILABLE_FOR_TIER 常量,NoModelForTier.code() 由共用 MODEL_UNAVAILABLE 改为 MODEL_UNAVAILABLE_FOR_TIER(仍 503),与单个模型不可用的 422 区分
- 更新 resolve_error_codes_are_stable 与 api-server llm 单测;收窄 llm/model_access 模块注释
- 同步设计文档 §11.4 与决策日志
2026-10-05 15:11:06 +08:00
k88936 c3866b4267 修复(后台邀请码): 拒绝补机器可读错误码走 400
- module-runtime 新增 RuntimeProfileInviteCodeAdminErrorCode(invalid_field / in_use),两个后台邀请码 procedure 结果末尾追加 error_code
- module 侧用 ProfileInviteCodeAdminProcedureError 在拒绝点赋码,字段校验统一 invalid_field、被他人占用归 in_use
- spacetime-client mapper 有码走 ProcedureRejected,并把 api-server 映射注释收窄为「带 typed code 的四条链路」
- 重新生成 SpacetimeDB 绑定;补 client 与 api-server 单测;同步设计文档 §5.8 与决策日志
2026-10-05 14:22:39 +08:00
k88936 e87837381a 修复(充值弹层): 下单进行中禁用泥点结算入口
- 会员订单提交时泥点结算 CTA 仍可点,点击后会被宿主 buyRechargeProduct 守卫静默丢弃
- 泥点结算弹层传 ctaDisabled,底部「充值」CTA 也在任意提交进行中禁用
- 保留上一轮「会员提交不波及泥点档位可选性」的既有行为,仅收口下单动作;补回归测试
2026-10-05 14:10:42 +08:00
k88936 cdbc6b4ac2 修复(充值弹层): max 档不再提示可补差升档
- 状态卡原先无条件显示「可同周期补差升档」,已是最高档时并无更高档位可升
- 父组件按启用目录计算 hasUpgradePath(存在 rank 更高的档位),无升级路径时只保留「周期切换需等到期后」
- 补 max 档与 plus 档的对照断言
2026-10-05 14:08:26 +08:00
k88936 f1a6c1eaac 修复(公历换算): days_from_civil 全量改用 i64 运算
- i32 年份区间内 era * 146_097 会超过 i32::MAX,debug 下 panic、release 下静默回绕
- 年、月、日中间量提升到 i64,返回类型仍是 i64;补 i32::MIN/MAX 边界回归测试
2026-10-05 14:05:07 +08:00
k88936 3a948c5f58 功能(充值弹层): 会员周期切换支持键盘方向键
- 月付/年付 radiogroup 原先无 roving tabindex,方向键无法移动选项
- 复用 resolveRovingIndex 与 ref,方向键同步移动选中与焦点;锁定时不响应方向键
- 补一条周期切换键盘导航测试
2026-10-05 14:03:48 +08:00
k88936 25bca13c31 类型(后台会员): 会员状态文案表改用命名联合类型
- membershipStatusLabels 原为 Record<string,string>,新增/改名状态时编译期无法发现漏配
- 改用 @genarrative/shared 的 ProfileMembershipStatus(normal/active),并把 AdminProfileMembershipPayload.status 的内联字面量一并替换
2026-10-05 13:59:14 +08:00
k88936 bf2addbae3 重构(会员档位页): 合并模型权限的重复文案映射
- 表单选项与列表摘要原先各写一份档位文案,措辞还不一致
- 抽出 modelAccessLabels 单一表,表单选项由它派生,列表摘要直接查表
2026-10-05 13:53:29 +08:00
k88936 5dc0654426 重构(AGC模型文案): 合并原因到文案的重复映射
- 两个 helper 原先各维护一份 reason switch,新增 reason 时容易漏改一处
- 抽成单个 REASON_COPY 表,unknown 作为未知/缺失原因的兜底,两个 helper 共用
2026-10-05 13:50:16 +08:00
k88936 4f3faa04b5 修复(后台兑换码): 管理拒绝补机器可读错误码走 400
Project CI / Backend tests (pull_request) Failing after 53s
Project CI / Native shell tests (pull_request) Failing after 3m51s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 5m25s
Project CI / Frontend tests (pull_request) Failing after 48s
Project CI / AI game creator shell web tests (pull_request) Failing after 43s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 6m17s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m6s
Project CI / Repository checks (pull_request) Successful in 4m37s
- module-runtime 新增 RuntimeProfileRedeemCodeAdminErrorCode(not_found / invalid_field / allowed_users_required),后台兑换码增改与列表 procedure 结果末尾追加 error_code
- module 侧用 ProfileRedeemCodeAdminProcedureError 在拒绝点赋码,字段校验统一 invalid_field、私有码缺用户 allowed_users_required
- spacetime-client 后台 mapper 有码走 ProcedureRejected,api-server 由此返回 400 而不是 502
- 重新生成 SpacetimeDB 绑定;补 client 与 api-server 单测;同步设计文档 §5.8 与决策日志
2026-10-05 12:35:55 +08:00
k88936 cc0c07223c 重构(会员契约): 充值中心会员状态改用强类型 token
- ProfileMembershipResponse.status 由裸 String 改为 ProfileMembershipStatusToken,与前端 ProfileMembershipStatus 对齐
- BFF 直接用 From<RuntimeProfileMembershipStatus> 转换,测试改用具名枚举
2026-10-05 12:22:28 +08:00
k88936 4bd080eff5 修复(LLM目录契约): 响应枚举未知取值前向兼容
- LlmModelsResponse 内 agentMode / protocol 遇到未知 token 回退 Codex / 由 agentMode 推导默认协议,不再让旧客户端整份反序列化失败
- 输入校验仍走严格 parse;补未知 token 用例
2026-10-05 12:19:15 +08:00
k88936 c7150b590c 修复(LLM目录契约): protocol 缺省改为按 agent_mode 推导
- LlmModelSummary/LlmUnavailableModel 反序列化缺失 protocol 时取 agent_mode 的默认协议,不再一律 openai_responses
- 补 cc / anthropic 别名 / 显式 protocol 用例;同步生成绑定注释
2026-10-05 12:18:05 +08:00
k88936 7579213bea 清理(AGC模型): 删除无档位校验的遗留 resolver
- 移除 AgcModelCatalog::resolve / resolve_requested,统一走带会员档位的 resolve_requested_for
- validate 内联默认项检查,测试改用 resolve_requested_for
2026-10-05 12:15:58 +08:00
k88936 af419e82c7 文档(泥点钱包): 统一三池合计的展示口径为可用总额
- mudPoints 文档不再声明合计「不代表可用额度」,与钱包入口/充值弹层的「可用总额」文案对齐
2026-10-05 12:14:53 +08:00
k88936 985b8718b8 清理(泥点定价): 移除硬编码的「¥1 = 10 泥点」文案
- 充值商品页描述去掉固定比例,不再把定价规则写死在 UI
- 同步去掉公共充值弹层与测试里同口径的注释
2026-10-05 12:14:20 +08:00
k88936 6d9125586a 文档(AGC模型): access 字段注释改为访问级别
- AdminAgcModel.access 与 AgcModel.access 的注释不再写成「会员档位」,避免与会员 plan 档位混淆
2026-10-05 12:01:43 +08:00
k88936 8bc48e9e61 修复(会员账期): 北京时间年份越界先收口再进历法换算
- beijing_local_micros 增加 ±292_278 年范围检查,避免 days_from_civil 内部 i32 乘法溢出
- 补充 10_000_000 年等溢出用例
2026-10-05 12:01:32 +08:00
k88936 0c9a16ba1a 修复(AGC模型): 未知权限档反序列化失败开放为 basic
- AgcModelAccess 将 Basic 放到最后一个变体并加 #[serde(other)],未知 access 不再让整份目录解析失败
- 补充未知 access 反序列化回退 Basic 的单测
2026-10-05 12:01:12 +08:00
k88936 d3f02d6bc9 修复(充值弹层): 泥点档位禁用范围收敛到泥点商品
- submittingProductId 现与会员下单共用,仅当提交的是泥点商品时才禁用整组泥点档位,避免会员提交期间跨页签耦合
2026-10-05 11:59:47 +08:00
k88936 f0dfddb910 修复(充值弹层): 未选中时左方向键回卷到最后一项
- resolveRovingIndex 的 currentIndex 允许为 -1,ArrowLeft 特判为 length-1,避免落到倒数第二项
2026-10-05 11:59:32 +08:00
k88936 5d2de88a40 修复(充值弹层): 当前档位缺失时禁用会员下单
- resolveMembershipPlanAction 在有效会员查不到当前档位时返回「套餐信息缺失」并禁用,避免误判为新客对所有档位开放购买
2026-10-05 11:59:12 +08:00
k88936 ff2bd5b57a 修复(用户详情): 会员状态按中文展示名渲染
- membershipDisplay 新增 formatMembershipStatus(normal→非会员、active→生效中,未知值原样返回)
- AdminUserDetailDialog 不再直接渲染后端 status token
2026-10-05 11:58:52 +08:00
k88936 589a2623a3 清理(后台假数据): 移除充值商品已退役的会员字段
- ProfileRechargeProductConfigAdminResponse 已无 tier/membershipPeriodPoints 等字段,假数据同步删除,避免掩盖前后端漂移
2026-10-05 11:57:48 +08:00
k88936 0a6c70a64f 修复(会员档位): 未知档位 code 回退展示原始值
- 列表与「最近保存」改用 formatMembershipPlan,未知 plan 不再渲染成空白
2026-10-05 11:57:39 +08:00
k88936 6e419d0d80 清理(后台工具): 删除无调用方的 parseNonNegativeIntegerOrZero
- 该函数与 parsePositiveIntegerOrZero 行为一致且无任何调用点,删除死代码
2026-10-05 11:57:28 +08:00
k88936 5a776f61ce 修复(充值商品): 保存前校验价格分与基础泥点为正整数
- AdminRechargeProductPage 改用严格 parsePositiveInteger 解析价格分与基础泥点
- 空串/非法输入直接提示表单错误,不再静默落库成 0 价或 0 泥点商品
2026-10-05 11:55:40 +08:00
k88936 48b6880955 修复(后台导航): 会员档位路由补入充值分组
- 将 membership-plans 加入 adminNavGroups 的 billing 分组,桌面端侧边栏不再漏掉「会员档位」入口
2026-10-05 11:55:29 +08:00
k88936 a48b7f8de8 Merge remote-tracking branch 'origin/master' into feat/pricing-plan
Project CI / Backend tests (pull_request) Failing after 48s
Project CI / Native shell tests (pull_request) Failing after 3m50s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 5m21s
Project CI / Frontend tests (pull_request) Failing after 47s
Project CI / AI game creator shell web tests (pull_request) Failing after 39s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 6m6s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m23s
Project CI / Repository checks (pull_request) Successful in 6m31s
# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
2026-10-05 10:50:30 +08:00
k88936 264f214fe5 docs(会员计费): 同步评审第 13–20 项的契约与实现口径
Project CI / Backend tests (pull_request) Failing after 28s
Project CI / Native shell tests (pull_request) Failing after 2m6s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m17s
Project CI / Frontend tests (pull_request) Failing after 45s
Project CI / Repository checks (pull_request) Failing after 18s
Project CI / AI game creator shell web tests (pull_request) Failing after 41s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 4m19s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 4m55s
- 后端架构文档:充点商品写入口收敛为 9 个字段,退役列保留且写死 0;首充赠送统一为 0
- 技术设计 §2.5/§5.7:补 ProfileMembershipStatusToken 与 5 个 token 枚举的 ts-rs 生成说明
- 技术设计 §11.4:AgcModelResolveError 增 NoModelForTier,模型解析错误统一走 typed AppError
- 决策记录:新增第 13–20 项收口条目,含影响范围与验证结论
2026-10-04 21:56:26 +08:00
k88936 14c147722a fix(会员结算): cycle_index==0 迁移行按 max(1) 归一,避免误判状态已变化
- frozen_membership_cycle_matches 比较双方都按 max(1) 归一(评审第 20 条)
- 存量 cycle_index 为 0 的会员行与投影的 Some(1) 快照现在判定一致,不再永久返回「会员状态已变化,请重新下单」
- 扩展 frozen_membership_cycle_identity_rejects_advanced_cycle 覆盖迁移行;已验证去掉 max(1) 时用例失败
2026-10-04 21:51:42 +08:00