类型化(会员错误):会员业务拒绝改用机器可读 error_code
- module-runtime 新增 RuntimeProfileMembershipErrorCode 与 RuntimeProfileMembershipDomainError - 会员报价 / 充值中心 / 后台档位 upsert 的 procedure 结果末尾追加 error_code - spacetime-module 在拒绝点显式赋码,中文 error_message 逐字保持不变 - spacetime-client 新增 SpacetimeClientError::ProcedureRejected 并映射生成绑定 - api-server 删除会员中文前缀分类,改按 error_code 返回 400,基础设施错误仍 502 - 重生成 module_bindings,并同步设计文档 5.8 与决策日志
This commit is contained in:
@@ -9585,3 +9585,12 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 影响范围:`server-rs/crates/shared-contracts/src/admin.rs`、`server-rs/crates/api-server/src/admin_recharge.rs`、`apps/admin-web/src/{api/adminApiTypes.ts,config/membershipDisplay.ts,pages/AdminMembershipPlanPage.tsx,pages/AdminRechargeOrderPage.tsx,components/AdminUserDetailDialog.tsx}`、`scripts/admin-web-fake-api.mjs`、设计文档 §5.6/§10.2、本文件。
|
||||
- 验证:`cargo check -p api-server`;`npm run admin-web:typecheck`;`npx vitest run apps/admin-web` → 26 files / 248 tests passed(新增「会员订单在发放泥点列展示会员变更快照」及用户详情会员断言)。
|
||||
- 边界:`/admin/api/*` 不在 `/api/external/v1` OpenAPI 门禁内,本次未补接口级契约测试,会员快照只在管理端页面用例层面取证。
|
||||
|
||||
## 2026-10-03 会员链路错误分类改为机器可读错误码(typed error)
|
||||
|
||||
- 背景:`api-server/src/runtime_profile.rs` 的 `is_runtime_profile_membership_domain_error` 用中文 `error_message` 前缀 / 精确匹配决定返回 400 还是 502;文案一改(或新增拒绝点)就静默退化,且分类逻辑与 module 的错误文案跨层重复。
|
||||
- 决策(错误码随 procedure 结果透传):`module-runtime` 新增 `RuntimeProfileMembershipErrorCode`(`UpgradeRejected` / `NotMember` / `AlreadyActive` / `CycleKindLocked` / `MembershipExpired` / `StateChanged` / `PlanNotPurchasable` / `PlanCatalogMissing` / `ProductIdUnparsable` / `MembershipProductRetired` / `InvalidPlanConfig`)与内部 `RuntimeProfileMembershipDomainError { code, message }`;三个会员 procedure 结果(升级报价、充值中心 / 下单、后台档位 upsert)末尾追加 `error_code: Option<...>`,拒绝点显式赋码,不再做字符串分类。
|
||||
- 决策(客户端错误类型):`spacetime-client` 新增 `SpacetimeClientError::ProcedureRejected { code, message }`;`api-server` 据此返回 400(provider `runtime-profile`),基础设施错误保持 502。字段校验类错误不产码,仍落 502。
|
||||
- 决策(行为变化):`会员目录缺少档位 ...` 与「已迁移的会员商品」原先落 502,现在明确 400;兑换码链路本轮未改造,仍保留一个文案匹配函数。procedure result 新增字段属 wire 契约变更,要求 module 与 api-server 同版本部署。
|
||||
- 影响范围:`server-rs/crates/module-runtime/src/domain.rs`、`server-rs/crates/spacetime-module/src/runtime/active/profile.rs`、`server-rs/crates/spacetime-client/src/{active.rs,active/mapper/runtime_profile.rs}`、生成绑定、`server-rs/crates/api-server/src/{runtime_profile.rs,asset_billing.rs,editor_project.rs}`、`docs/technical/【技术设计】泥点三池与会员计费后端设计-2026-10-02.md` §5.8、本文件。
|
||||
- 验证:`npm run spacetime:generate`;`cargo check --workspace`;`api-server runtime_profile::tests` 41 passed;`module-runtime --lib membership::` 39 passed;`npm run check:encoding`、`npm run check:spacetime-schema`、`cargo fmt -- --check`、`git diff --check` 通过。
|
||||
|
||||
@@ -433,6 +433,24 @@ flowchart TD
|
||||
- `npm run check:generated-bindings` 以「重新生成并与工作区逐字节比较」做门禁,防止 Rust 改了而生成文件没重跑。
|
||||
- 需要展示用派生字段(如 `totalPoints` 合计)时,在前端 `utils/mudPoints.ts` 里派生,不改 DTO。
|
||||
|
||||
### 5.8 会员错误码契约(typed error,已落地)
|
||||
|
||||
- 会员链路的业务拒绝不再靠中文 `error_message` 前缀分类。`module-runtime` 新增
|
||||
`RuntimeProfileMembershipErrorCode`(`UpgradeRejected` / `NotMember` / `AlreadyActive` /
|
||||
`CycleKindLocked` / `MembershipExpired` / `StateChanged` / `PlanNotPurchasable` /
|
||||
`PlanCatalogMissing` / `ProductIdUnparsable` / `MembershipProductRetired` / `InvalidPlanConfig`),
|
||||
在拒绝点显式产出,`RuntimeProfileMembershipUpgradeQuoteProcedureResult` /
|
||||
`RuntimeProfileRechargeCenterProcedureResult` / `RuntimeProfileMembershipPlanAdminProcedureResult`
|
||||
末尾追加 `error_code: Option<RuntimeProfileMembershipErrorCode>`(`error_message` 保留人读文案)。
|
||||
- `spacetime-client` 的 `SpacetimeClientError` 新增
|
||||
`ProcedureRejected { code, message }`;`api-server` 的 `runtime_profile` 映射据此返回 400
|
||||
(`provider = runtime-profile`),基础设施错误保持 502。字段校验类错误(如 user_id 缺失)
|
||||
不产出 `error_code`,仍按字符串错误落到 502。
|
||||
- 行为变化:`会员目录缺少档位 ...` 与「已迁移的会员商品」原先落到 502,现在有明确错误码,统一 400。
|
||||
- 兼容边界:procedure result 是 wire 结构,新增字段要求 module 与 api-server 同版本部署;
|
||||
旧 module 不返回 `error_code` 时,新 client 绑定反序列化会失败。兑换码链路本轮未改造,
|
||||
`api-server` 仍保留一个兑换码文案匹配函数。
|
||||
|
||||
---
|
||||
|
||||
## 6. 计算规则(后端唯一真相源)
|
||||
|
||||
@@ -695,6 +695,8 @@ fn should_use_wallet_refund_emergency_spool(error: &SpacetimeClientError) -> boo
|
||||
|| message.contains("连接已断开")
|
||||
|| message.contains("连接在返回结果前已断开")
|
||||
}
|
||||
// 业务拒绝是服务端已明确应答,不应触发退款应急 spool。
|
||||
SpacetimeClientError::ProcedureRejected { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1149,6 +1149,7 @@ fn is_editor_generation_retryable_transport_error(error: &SpacetimeClientError)
|
||||
|| message.contains("连接在返回结果前已断开")
|
||||
}
|
||||
SpacetimeClientError::Procedure(_) => false,
|
||||
SpacetimeClientError::ProcedureRejected { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,6 +1161,7 @@ fn is_editor_generation_unknown_result_error(
|
||||
&& !matches!(
|
||||
error,
|
||||
SpacetimeClientError::Procedure(_)
|
||||
| SpacetimeClientError::ProcedureRejected { .. }
|
||||
| SpacetimeClientError::Timeout(
|
||||
SpacetimeClientStage::PoolAcquire
|
||||
| SpacetimeClientStage::ConnectBuild
|
||||
|
||||
@@ -1463,13 +1463,12 @@ pub async fn get_profile_play_stats(
|
||||
}
|
||||
|
||||
fn map_runtime_profile_client_error(error: SpacetimeClientError) -> AppError {
|
||||
let is_domain_error = matches!(
|
||||
&error,
|
||||
SpacetimeClientError::Procedure(message)
|
||||
if is_runtime_profile_domain_error(message)
|
||||
);
|
||||
let is_domain_error = is_runtime_profile_domain_error(&error);
|
||||
let (status, provider) = match &error {
|
||||
SpacetimeClientError::Runtime(_) => (StatusCode::BAD_REQUEST, "runtime-profile"),
|
||||
SpacetimeClientError::ProcedureRejected { .. } => {
|
||||
(StatusCode::BAD_REQUEST, "runtime-profile")
|
||||
}
|
||||
SpacetimeClientError::Procedure(_) if is_domain_error => {
|
||||
(StatusCode::BAD_REQUEST, "runtime-profile")
|
||||
}
|
||||
@@ -1487,24 +1486,18 @@ fn map_runtime_profile_client_error(error: SpacetimeClientError) -> AppError {
|
||||
}
|
||||
|
||||
/// 模块侧的可读业务拒绝以 400 返回,基础设施错误保持 502。
|
||||
fn is_runtime_profile_domain_error(message: &str) -> bool {
|
||||
is_runtime_profile_redeem_code_domain_error(message)
|
||||
|| is_runtime_profile_membership_domain_error(message)
|
||||
}
|
||||
|
||||
fn is_runtime_profile_membership_domain_error(message: &str) -> bool {
|
||||
message.starts_with("会员升级被拒绝: ")
|
||||
|| message.starts_with("会员档位")
|
||||
|| message.starts_with("会员商品 product_id 无法解析: ")
|
||||
|| message.starts_with("充值商品类型无效:会员商品已迁移到会员档位目录")
|
||||
|| matches!(
|
||||
message,
|
||||
"当前不是会员,请直接选择套餐购买"
|
||||
| "当前套餐已生效,无需重复购买"
|
||||
| "当前会员有效期内不支持月付 / 年付转换,到期后可重新选择"
|
||||
| "会员已到期,请按新购价格重新下单"
|
||||
| "会员状态已变化,请重新下单"
|
||||
)
|
||||
///
|
||||
/// 会员链路的拒绝已由 SpacetimeDB procedure 透传机器可读错误码,走
|
||||
/// [`SpacetimeClientError::ProcedureRejected`];兑换码尚未改造,仍按可读文案匹配(见
|
||||
/// [`is_runtime_profile_redeem_code_domain_error`])。
|
||||
fn is_runtime_profile_domain_error(error: &SpacetimeClientError) -> bool {
|
||||
match error {
|
||||
SpacetimeClientError::ProcedureRejected { .. } => true,
|
||||
SpacetimeClientError::Procedure(message) => {
|
||||
is_runtime_profile_redeem_code_domain_error(message)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_runtime_profile_redeem_code_domain_error(message: &str) -> bool {
|
||||
@@ -2534,12 +2527,12 @@ mod tests {
|
||||
use module_runtime::{
|
||||
PROFILE_RECHARGE_PAYMENT_CHANNEL_WECHAT_MINI_PROGRAM_VIRTUAL,
|
||||
RuntimeProfileDailyFreePointsRecord, RuntimeProfileMembershipCycleKind,
|
||||
RuntimeProfileMembershipModelAccess, RuntimeProfileMembershipPlan,
|
||||
RuntimeProfileMembershipPlanRecord, RuntimeProfileMembershipRecord,
|
||||
RuntimeProfileMembershipStatus, RuntimeProfileRechargeCenterRecord,
|
||||
RuntimeProfileRechargeOrderRecord, RuntimeProfileRechargeOrderStatus,
|
||||
RuntimeProfileRechargeProductKind, RuntimeProfileRechargeProductRecord,
|
||||
RuntimeProfileWalletLedgerSourceType,
|
||||
RuntimeProfileMembershipErrorCode, RuntimeProfileMembershipModelAccess,
|
||||
RuntimeProfileMembershipPlan, RuntimeProfileMembershipPlanRecord,
|
||||
RuntimeProfileMembershipRecord, RuntimeProfileMembershipStatus,
|
||||
RuntimeProfileRechargeCenterRecord, RuntimeProfileRechargeOrderRecord,
|
||||
RuntimeProfileRechargeOrderStatus, RuntimeProfileRechargeProductKind,
|
||||
RuntimeProfileRechargeProductRecord, RuntimeProfileWalletLedgerSourceType,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -2587,20 +2580,48 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn membership_business_rejections_map_to_bad_request() {
|
||||
// 中文注释:会员商品迁档位目录后的业务拒绝必须按 400 返回;漏掉前缀匹配会落到 502,
|
||||
// 让后台与下单端把可读的业务提示当成基础设施故障。目录缺行属于部署配置错误,保持 502。
|
||||
for message in [
|
||||
"会员升级被拒绝: cycle_kind_change_unsupported",
|
||||
"会员商品 product_id 无法解析: membership-pro-yearly",
|
||||
"充值商品类型无效:会员商品已迁移到会员档位目录",
|
||||
// 中文注释:会员业务拒绝由 procedure 透传机器可读 error_code,统一按 400 返回;
|
||||
// 中文文案不再参与分类,普通 Procedure 字符串错误保持 502。
|
||||
for (code, message) in [
|
||||
(
|
||||
RuntimeProfileMembershipErrorCode::UpgradeRejected,
|
||||
"会员升级被拒绝: cycle_kind_change_unsupported",
|
||||
),
|
||||
(
|
||||
RuntimeProfileMembershipErrorCode::ProductIdUnparsable,
|
||||
"会员商品 product_id 无法解析: membership-pro-yearly",
|
||||
),
|
||||
(
|
||||
RuntimeProfileMembershipErrorCode::MembershipProductRetired,
|
||||
"充值商品类型无效:会员商品已迁移到会员档位目录",
|
||||
),
|
||||
(
|
||||
RuntimeProfileMembershipErrorCode::PlanCatalogMissing,
|
||||
"会员目录缺少档位 pro",
|
||||
),
|
||||
] {
|
||||
let error = map_runtime_profile_client_error(SpacetimeClientError::Procedure(
|
||||
message.to_string(),
|
||||
));
|
||||
let error = map_runtime_profile_client_error(SpacetimeClientError::ProcedureRejected {
|
||||
code,
|
||||
message: message.to_string(),
|
||||
});
|
||||
|
||||
assert_eq!(error.status_code(), StatusCode::BAD_REQUEST, "{message}");
|
||||
assert_eq!(error.message(), message);
|
||||
assert_eq!(
|
||||
error
|
||||
.details()
|
||||
.and_then(|details| details.get("provider"))
|
||||
.and_then(Value::as_str),
|
||||
Some("runtime-profile")
|
||||
);
|
||||
}
|
||||
|
||||
// 中文注释:删掉字符串前缀分类后,同样的文案若没有 error_code 必须落到 502。
|
||||
let legacy_string_error =
|
||||
map_runtime_profile_client_error(SpacetimeClientError::Procedure(
|
||||
"会员升级被拒绝: cycle_kind_change_unsupported".to_string(),
|
||||
));
|
||||
assert_eq!(legacy_string_error.status_code(), StatusCode::BAD_GATEWAY);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1467,6 +1467,82 @@ impl From<shared_contracts::runtime::ProfileMembershipChangeKindToken>
|
||||
}
|
||||
}
|
||||
|
||||
/// 会员业务拒绝的机器可读错误码。
|
||||
///
|
||||
/// 会员链路的人读 `error_message` 会随文案调整,调用方不得再按中文字符串判断 HTTP 状态;
|
||||
/// 每个拒绝点显式产出本枚举,随 procedure 结果透传到 Axum 侧。
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum RuntimeProfileMembershipErrorCode {
|
||||
/// 补差升级报价 / 下单被升级规则拒绝。
|
||||
UpgradeRejected,
|
||||
/// 当前不是会员,应直接购买套餐。
|
||||
NotMember,
|
||||
/// 当前套餐已生效,无需重复购买。
|
||||
AlreadyActive,
|
||||
/// 有效期内不支持月付 / 年付转换。
|
||||
CycleKindLocked,
|
||||
/// 会员已到期,需按新购价格重新下单。
|
||||
MembershipExpired,
|
||||
/// 下单后会员状态已变化,需要重新下单。
|
||||
StateChanged,
|
||||
/// 目标档位当前不可购买。
|
||||
PlanNotPurchasable,
|
||||
/// 代码内档位目录缺少该档位。
|
||||
PlanCatalogMissing,
|
||||
/// 会员商品 product_id 无法解析。
|
||||
ProductIdUnparsable,
|
||||
/// 会员商品已迁移到档位目录,旧商品不再可用。
|
||||
MembershipProductRetired,
|
||||
/// 后台会员档位改价 / 改权益配置校验失败。
|
||||
InvalidPlanConfig,
|
||||
}
|
||||
|
||||
impl RuntimeProfileMembershipErrorCode {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::UpgradeRejected => "upgrade_rejected",
|
||||
Self::NotMember => "not_member",
|
||||
Self::AlreadyActive => "already_active",
|
||||
Self::CycleKindLocked => "cycle_kind_locked",
|
||||
Self::MembershipExpired => "membership_expired",
|
||||
Self::StateChanged => "state_changed",
|
||||
Self::PlanNotPurchasable => "plan_not_purchasable",
|
||||
Self::PlanCatalogMissing => "plan_catalog_missing",
|
||||
Self::ProductIdUnparsable => "product_id_unparsable",
|
||||
Self::MembershipProductRetired => "membership_product_retired",
|
||||
Self::InvalidPlanConfig => "invalid_plan_config",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 会员领域错误:机器可读 `code` + 人读 `message`。
|
||||
///
|
||||
/// 只在模块内部与 procedure 结果装载之间传递,不落 SpacetimeDB 表,因此不派生 `SpacetimeType`。
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct RuntimeProfileMembershipDomainError {
|
||||
pub code: RuntimeProfileMembershipErrorCode,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl RuntimeProfileMembershipDomainError {
|
||||
pub fn new(code: RuntimeProfileMembershipErrorCode, message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
code,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for RuntimeProfileMembershipDomainError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for RuntimeProfileMembershipDomainError {}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum RuntimeProfileRechargeOrderStatus {
|
||||
@@ -1888,6 +1964,7 @@ pub struct RuntimeProfileRechargeCenterProcedureResult {
|
||||
pub record: Option<RuntimeProfileRechargeCenterSnapshot>,
|
||||
pub order: Option<RuntimeProfileRechargeOrderSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
pub error_code: Option<RuntimeProfileMembershipErrorCode>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
@@ -1969,6 +2046,7 @@ pub struct RuntimeProfileMembershipPlanAdminProcedureResult {
|
||||
pub ok: bool,
|
||||
pub record: Option<RuntimeProfileMembershipPlanRecord>,
|
||||
pub error_message: Option<String>,
|
||||
pub error_code: Option<RuntimeProfileMembershipErrorCode>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
@@ -2019,6 +2097,7 @@ pub struct RuntimeProfileMembershipUpgradeQuoteProcedureResult {
|
||||
pub ok: bool,
|
||||
pub quote: Option<RuntimeProfileMembershipUpgradeQuoteSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
pub error_code: Option<RuntimeProfileMembershipErrorCode>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
|
||||
@@ -233,6 +233,11 @@ pub enum SpacetimeClientError {
|
||||
Build(String),
|
||||
ConnectDropped,
|
||||
Procedure(String),
|
||||
/// 会员 procedure 返回了带机器可读错误码的业务拒绝。
|
||||
ProcedureRejected {
|
||||
code: module_runtime::RuntimeProfileMembershipErrorCode,
|
||||
message: String,
|
||||
},
|
||||
Runtime(String),
|
||||
Timeout(SpacetimeClientStage),
|
||||
}
|
||||
@@ -991,6 +996,16 @@ impl SpacetimeClientError {
|
||||
Self::Procedure(message.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()))
|
||||
}
|
||||
|
||||
pub(crate) fn procedure_rejected(
|
||||
code: module_runtime::RuntimeProfileMembershipErrorCode,
|
||||
message: Option<String>,
|
||||
) -> Self {
|
||||
Self::ProcedureRejected {
|
||||
code,
|
||||
message: message.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn missing_snapshot(label: &'static str) -> Self {
|
||||
Self::Procedure(format!("SpacetimeDB procedure 未返回{label}"))
|
||||
}
|
||||
@@ -1073,6 +1088,7 @@ impl fmt::Display for SpacetimeClientError {
|
||||
Self::Build(message) | Self::Procedure(message) | Self::Runtime(message) => {
|
||||
f.write_str(message)
|
||||
}
|
||||
Self::ProcedureRejected { message, .. } => f.write_str(message),
|
||||
Self::ConnectDropped => f.write_str("SpacetimeDB 连接在返回结果前已断开"),
|
||||
Self::Timeout(stage) => {
|
||||
f.write_str(&format!("SpacetimeDB {} 调用超时", stage.as_str()))
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
use super::*;
|
||||
|
||||
/// 会员 procedure 失败统一落错误:有机器可读 `error_code` 时走 `ProcedureRejected`,否则回退字符串错误。
|
||||
pub(crate) fn map_runtime_profile_membership_procedure_failure(
|
||||
error_code: Option<crate::module_bindings::RuntimeProfileMembershipErrorCode>,
|
||||
error_message: Option<String>,
|
||||
) -> SpacetimeClientError {
|
||||
match error_code {
|
||||
Some(code) => SpacetimeClientError::procedure_rejected(
|
||||
map_runtime_profile_membership_error_code_back(code),
|
||||
error_message,
|
||||
),
|
||||
None => SpacetimeClientError::procedure_failed(error_message),
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeProfileDashboardGetInput> for RuntimeProfileDashboardGetInput {
|
||||
fn from(input: module_runtime::RuntimeProfileDashboardGetInput) -> Self {
|
||||
Self {
|
||||
@@ -736,7 +750,10 @@ pub(crate) fn map_runtime_profile_recharge_center_procedure_result(
|
||||
result: RuntimeProfileRechargeCenterProcedureResult,
|
||||
) -> Result<RuntimeProfileRechargeCenterRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
return Err(map_runtime_profile_membership_procedure_failure(
|
||||
result.error_code,
|
||||
result.error_message,
|
||||
));
|
||||
}
|
||||
|
||||
let snapshot = result
|
||||
@@ -772,7 +789,10 @@ pub(crate) fn map_runtime_profile_recharge_order_procedure_result(
|
||||
SpacetimeClientError,
|
||||
> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
return Err(map_runtime_profile_membership_procedure_failure(
|
||||
result.error_code,
|
||||
result.error_message,
|
||||
));
|
||||
}
|
||||
|
||||
let center = result
|
||||
@@ -2032,6 +2052,46 @@ pub(crate) fn map_runtime_profile_membership_change_kind_back(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_profile_membership_error_code_back(
|
||||
value: crate::module_bindings::RuntimeProfileMembershipErrorCode,
|
||||
) -> module_runtime::RuntimeProfileMembershipErrorCode {
|
||||
match value {
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::UpgradeRejected => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::UpgradeRejected
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::NotMember => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::NotMember
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::AlreadyActive => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::AlreadyActive
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::CycleKindLocked => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::CycleKindLocked
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::MembershipExpired => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::MembershipExpired
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::StateChanged => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::StateChanged
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::PlanNotPurchasable => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::PlanNotPurchasable
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::PlanCatalogMissing => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::PlanCatalogMissing
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::ProductIdUnparsable => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::ProductIdUnparsable
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::MembershipProductRetired => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::MembershipProductRetired
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileMembershipErrorCode::InvalidPlanConfig => {
|
||||
module_runtime::RuntimeProfileMembershipErrorCode::InvalidPlanConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_profile_membership_model_access(
|
||||
value: module_runtime::RuntimeProfileMembershipModelAccess,
|
||||
) -> crate::module_bindings::RuntimeProfileMembershipModelAccess {
|
||||
@@ -2131,7 +2191,10 @@ pub(crate) fn map_runtime_profile_membership_upgrade_quote_procedure_result(
|
||||
result: RuntimeProfileMembershipUpgradeQuoteProcedureResult,
|
||||
) -> Result<module_runtime::RuntimeProfileMembershipUpgradeQuoteRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
return Err(map_runtime_profile_membership_procedure_failure(
|
||||
result.error_code,
|
||||
result.error_message,
|
||||
));
|
||||
}
|
||||
|
||||
let quote = result
|
||||
@@ -2173,7 +2236,10 @@ pub(crate) fn map_runtime_profile_membership_plan_admin_procedure_result(
|
||||
result: RuntimeProfileMembershipPlanAdminProcedureResult,
|
||||
) -> Result<module_runtime::RuntimeProfileMembershipPlanRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
return Err(map_runtime_profile_membership_procedure_failure(
|
||||
result.error_code,
|
||||
result.error_message,
|
||||
));
|
||||
}
|
||||
|
||||
let record = result
|
||||
|
||||
@@ -705,6 +705,7 @@ pub mod runtime_profile_invite_code_admin_upsert_input_type;
|
||||
pub mod runtime_profile_invite_code_snapshot_type;
|
||||
pub mod runtime_profile_membership_change_kind_type;
|
||||
pub mod runtime_profile_membership_cycle_kind_type;
|
||||
pub mod runtime_profile_membership_error_code_type;
|
||||
pub mod runtime_profile_membership_get_input_type;
|
||||
pub mod runtime_profile_membership_model_access_type;
|
||||
pub mod runtime_profile_membership_order_change_snapshot_type;
|
||||
@@ -1579,6 +1580,7 @@ pub use runtime_profile_invite_code_admin_upsert_input_type::RuntimeProfileInvit
|
||||
pub use runtime_profile_invite_code_snapshot_type::RuntimeProfileInviteCodeSnapshot;
|
||||
pub use runtime_profile_membership_change_kind_type::RuntimeProfileMembershipChangeKind;
|
||||
pub use runtime_profile_membership_cycle_kind_type::RuntimeProfileMembershipCycleKind;
|
||||
pub use runtime_profile_membership_error_code_type::RuntimeProfileMembershipErrorCode;
|
||||
pub use runtime_profile_membership_get_input_type::RuntimeProfileMembershipGetInput;
|
||||
pub use runtime_profile_membership_model_access_type::RuntimeProfileMembershipModelAccess;
|
||||
pub use runtime_profile_membership_order_change_snapshot_type::RuntimeProfileMembershipOrderChangeSnapshot;
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
#[derive(Copy, Eq, Hash)]
|
||||
pub enum RuntimeProfileMembershipErrorCode {
|
||||
UpgradeRejected,
|
||||
|
||||
NotMember,
|
||||
|
||||
AlreadyActive,
|
||||
|
||||
CycleKindLocked,
|
||||
|
||||
MembershipExpired,
|
||||
|
||||
StateChanged,
|
||||
|
||||
PlanNotPurchasable,
|
||||
|
||||
PlanCatalogMissing,
|
||||
|
||||
ProductIdUnparsable,
|
||||
|
||||
MembershipProductRetired,
|
||||
|
||||
InvalidPlanConfig,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileMembershipErrorCode {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
+2
@@ -4,6 +4,7 @@
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::runtime_profile_membership_error_code_type::RuntimeProfileMembershipErrorCode;
|
||||
use super::runtime_profile_membership_plan_record_type::RuntimeProfileMembershipPlanRecord;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
@@ -12,6 +13,7 @@ pub struct RuntimeProfileMembershipPlanAdminProcedureResult {
|
||||
pub ok: bool,
|
||||
pub record: Option<RuntimeProfileMembershipPlanRecord>,
|
||||
pub error_message: Option<String>,
|
||||
pub error_code: Option<RuntimeProfileMembershipErrorCode>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileMembershipPlanAdminProcedureResult {
|
||||
|
||||
+2
@@ -4,6 +4,7 @@
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::runtime_profile_membership_error_code_type::RuntimeProfileMembershipErrorCode;
|
||||
use super::runtime_profile_membership_upgrade_quote_snapshot_type::RuntimeProfileMembershipUpgradeQuoteSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
@@ -12,6 +13,7 @@ pub struct RuntimeProfileMembershipUpgradeQuoteProcedureResult {
|
||||
pub ok: bool,
|
||||
pub quote: Option<RuntimeProfileMembershipUpgradeQuoteSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
pub error_code: Option<RuntimeProfileMembershipErrorCode>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileMembershipUpgradeQuoteProcedureResult {
|
||||
|
||||
+2
@@ -4,6 +4,7 @@
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::runtime_profile_membership_error_code_type::RuntimeProfileMembershipErrorCode;
|
||||
use super::runtime_profile_recharge_center_snapshot_type::RuntimeProfileRechargeCenterSnapshot;
|
||||
use super::runtime_profile_recharge_order_snapshot_type::RuntimeProfileRechargeOrderSnapshot;
|
||||
|
||||
@@ -14,6 +15,7 @@ pub struct RuntimeProfileRechargeCenterProcedureResult {
|
||||
pub record: Option<RuntimeProfileRechargeCenterSnapshot>,
|
||||
pub order: Option<RuntimeProfileRechargeOrderSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
pub error_code: Option<RuntimeProfileMembershipErrorCode>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileRechargeCenterProcedureResult {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user