统一发布 bootstrap 在事务内补必填文本校验
在 `get_or_create_game_distribution_game_for_publish_tx` 落库前校验 title/summary/category/orientation 非空,与旧 create_game 同口径,不假设 api-server 是唯一调用方 新增源码结构回归测试
This commit is contained in:
@@ -3816,16 +3816,23 @@ fn get_or_create_game_distribution_game_for_publish_tx(
|
||||
}
|
||||
}
|
||||
|
||||
// 事务内最后一道非空防线:api-server 已校验,但这条 get-or-create 是公开 procedure 的落库点,
|
||||
// 不能假设只有那一个调用方(与旧 `create_game_distribution_game_tx` 同口径)。
|
||||
let title = required_game_distribution_text(input.title.clone(), "title")?;
|
||||
let summary = required_game_distribution_text(input.summary.clone(), "summary")?;
|
||||
let category = required_game_distribution_text(input.category.clone(), "category")?;
|
||||
let orientation = required_game_distribution_text(input.orientation.clone(), "orientation")?;
|
||||
|
||||
let now = Timestamp::from_micros_since_unix_epoch(input.now_micros);
|
||||
ctx.db
|
||||
.game_distribution_game()
|
||||
.insert(GameDistributionGame {
|
||||
game_id: input.game_id.clone(),
|
||||
owner_user_id: owner_user_id.to_string(),
|
||||
title: input.title.clone(),
|
||||
summary: input.summary.clone(),
|
||||
title,
|
||||
summary,
|
||||
description: input.description.clone().unwrap_or_default(),
|
||||
category: input.category.clone(),
|
||||
category,
|
||||
tags_json: input.tags_json.clone(),
|
||||
cover_asset_id: None,
|
||||
author_name: input.author_name.clone(),
|
||||
@@ -3834,7 +3841,7 @@ fn get_or_create_game_distribution_game_for_publish_tx(
|
||||
device_support_mobile: input.device_support_mobile,
|
||||
device_support_touch: input.device_support_touch,
|
||||
input_modes_json: input.input_modes_json.clone(),
|
||||
orientation: input.orientation.clone(),
|
||||
orientation,
|
||||
publication_revision: 0,
|
||||
active_version_id: None,
|
||||
visibility: GAME_DISTRIBUTION_VISIBILITY_UNPUBLISHED.to_string(),
|
||||
@@ -8477,6 +8484,28 @@ mod tests {
|
||||
panic!("{marker} 的函数体不闭合");
|
||||
}
|
||||
|
||||
/// get-or-create 的作品行落库点必须自己再校验一次必填文本。
|
||||
///
|
||||
/// api-server 是当前唯一调用方,但这是公开 procedure 的落库点;与旧
|
||||
/// `create_game_distribution_game_tx` 同口径,空标题 / 空分类 / 未知 orientation 必须在事务内
|
||||
/// 失败关闭,而不是写进脏行。
|
||||
#[test]
|
||||
fn bootstrap_publish_game_validates_required_text_before_insert() {
|
||||
let source = include_str!("game_distribution.rs");
|
||||
let body = function_body(
|
||||
source,
|
||||
"fn get_or_create_game_distribution_game_for_publish_tx(",
|
||||
);
|
||||
for field in ["title", "summary", "category", "orientation"] {
|
||||
assert!(
|
||||
body.contains(&format!(
|
||||
"required_game_distribution_text(input.{field}.clone(), \"{field}\")?"
|
||||
)),
|
||||
"作品行 bootstrap 必须校验 {field}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 版本表的 `change_summary` 必须留在**表尾**并带默认值。
|
||||
///
|
||||
/// schema guard 只允许「末尾追加 + 显式默认」:插在中间会让既有行的列序整体错位(不是迁移能补
|
||||
|
||||
Reference in New Issue
Block a user