From 8e1471d7af9544afefb9a5e031dba2000d694cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 2 Oct 2026 19:23:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95(=E8=AE=A1=E8=B4=B9):=20?= =?UTF-8?q?=E5=9B=BA=E5=8C=96=E4=BC=9A=E5=91=98=E7=9B=AE=E5=BD=95=E4=BB=B7?= =?UTF-8?q?=E6=A0=BC=E4=B8=8E=E6=B3=A5=E7=82=B9=E9=9A=8F=20rank=20?= =?UTF-8?q?=E9=80=92=E5=A2=9E=E7=9A=84=E4=B8=8D=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 catalog 文档写明升级补差依赖的单调性不变量,并新增回归测试断言 rank 越高月价、年价、每期泥点严格递增 Co-authored-by: Junie --- .../module-runtime/src/membership/catalog.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/server-rs/crates/module-runtime/src/membership/catalog.rs b/server-rs/crates/module-runtime/src/membership/catalog.rs index 1fee74750..e7d2860e3 100644 --- a/server-rs/crates/module-runtime/src/membership/catalog.rs +++ b/server-rs/crates/module-runtime/src/membership/catalog.rs @@ -8,6 +8,10 @@ //! 价格是**后端唯一真相**,前端展示价只用于渲染,下单时后端按同一份目录重算。 //! //! 本期模型权限只落字段、只用于展示,不做服务端拦截;并发上限只做判定,同样不拦截。 +//! +//! 目录不变量:按 `rank` 升序,月价、年价、每期泥点必须**严格递增**(`Normal` 为 0)。 +//! 升级补差按 `rank` 判定、按价差 / 点差计价,若高 `rank` 的行反而更便宜或更少点, +//! `saturating_sub` 会把补差静默算成 0;后台改价时不得破坏该不变量。 use serde::{Deserialize, Serialize}; @@ -298,6 +302,35 @@ mod tests { assert!(is_unlimited_concurrency(max.concurrent_job_limit)); } + #[test] + fn enabled_plans_increase_in_price_and_points_with_rank() { + // 中文注释:升级补差依赖「rank 越高、价格与每期泥点越大」这一不变量; + // 后台改价破坏它时,升级会静默算成 0,因此把种子目录的不变量固化成回归断言。 + let mut rows = runtime_profile_membership_plan_catalog(); + rows.sort_by_key(|row| row.rank); + for pair in rows.windows(2) { + let (lower, higher) = (&pair[0], &pair[1]); + assert!( + higher.month_price_cents > lower.month_price_cents, + "{} 的月价必须高于 {}", + higher.title, + lower.title + ); + assert!( + higher.year_price_cents > lower.year_price_cents, + "{} 的年价必须高于 {}", + higher.title, + lower.title + ); + assert!( + higher.period_points > lower.period_points, + "{} 的每期泥点必须高于 {}", + higher.title, + lower.title + ); + } + } + #[test] fn year_price_is_stored_independently_of_the_month_price() { // 中文注释:年价是独立可配置字段,这里断言的是种子数值本身,而不是月价 ×10 的推导关系。