实现后台游戏评价管理
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled

新增后台评价查询分页、详情和独立页面权限
支持管理员隐藏、恢复和删除评价,隐藏删除必须填写原因
新增私有操作记录及幂等重试保护,兼容升级评价隐藏字段
同步网站隐藏提示、公开评价列表和评分统计
补充定向测试、运行时验证脚本及方案验收证据
This commit is contained in:
2026-10-01 12:22:13 +08:00
parent 264fdee747
commit cb689fea2a
52 changed files with 4579 additions and 56 deletions
+67
View File
@@ -2215,6 +2215,12 @@ fn admin_permission_requirement(_method: &Method, path: &str) -> AdminPermission
"/admin/api/editor-assets" => AnyTab(&["editor-assets"]),
"/admin/api/assets/read-url" => AnyTab(&["editor-assets", "editor-showcase"]),
path if path.starts_with("/admin/api/editor-showcase/") => AnyTab(&["editor-showcase"]),
"/admin/api/game-distribution/user-review-games" => AnyTab(&["game-reviews"]),
path if path == "/admin/api/game-distribution/user-reviews"
|| path.starts_with("/admin/api/game-distribution/user-reviews/") =>
{
AnyTab(&["game-reviews"])
}
path if path.starts_with("/admin/api/game-distribution/reviews") => {
AnyTab(&["editor-showcase"])
}
@@ -7502,6 +7508,67 @@ mod tests {
);
}
#[test]
fn game_reviews_tab_authorizes_all_user_review_routes_only() {
for (method, path) in [
(
Method::GET,
"/admin/api/game-distribution/user-review-games",
),
(Method::GET, "/admin/api/game-distribution/user-reviews"),
(
Method::GET,
"/admin/api/game-distribution/user-reviews/review_1",
),
(
Method::POST,
"/admin/api/game-distribution/user-reviews/review_1/moderation",
),
] {
assert!(enforce_admin_request_permission("owner", &[], &[], &method, path).is_ok());
assert!(
enforce_admin_request_permission(
"member",
&["game-reviews".into()],
&[],
&method,
path
)
.is_ok()
);
for permissions in [
vec![],
vec!["game-management".into()],
vec!["editor-showcase".into()],
] {
assert_eq!(
enforce_admin_request_permission("member", &permissions, &[], &method, path)
.unwrap_err()
.status_code(),
StatusCode::FORBIDDEN
);
}
}
for path in [
"/admin/api/game-distribution/reviews",
"/admin/api/game-distribution/games",
"/admin/api/game-distribution/versions/version_1/review",
] {
assert_eq!(
enforce_admin_request_permission(
"member",
&["game-reviews".into()],
&[],
&Method::GET,
path
)
.unwrap_err()
.status_code(),
StatusCode::FORBIDDEN
);
}
}
#[test]
fn wallet_consumption_reconcile_requires_its_standalone_action_permission() {
assert!(
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,10 @@ mod release;
mod reviews;
pub use reviews::{
UserReviewValidationError, normalize_review_comment, review_id, review_order, review_summary,
ReviewModerationValidationError, UserReviewValidationError, normalize_review_comment,
normalize_review_moderation_reason, review_id, review_matches_filters,
review_moderation_operation_id, review_order, review_summary, validate_review_list_status,
visible_review_summary,
};
pub use application::{
@@ -46,6 +46,14 @@ pub fn review_summary(scores: impl Iterator<Item = i64>) -> (Option<f64>, u64) {
(average, count)
}
pub fn visible_review_summary(reviews: impl Iterator<Item = (i64, bool)>) -> (Option<f64>, u64) {
review_summary(
reviews
.filter(|(_, is_hidden)| !is_hidden)
.map(|(score, _)| score),
)
}
pub fn review_order(
left_created: i64,
left_id: &str,
@@ -57,6 +65,72 @@ pub fn review_order(
.then_with(|| right_id.cmp(left_id))
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ReviewModerationValidationError {
InvalidAction,
InvalidStatus,
InvalidReason,
}
impl fmt::Display for ReviewModerationValidationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::InvalidAction => "REVIEW_BAD_REQUEST: 管理动作须为 hide、restore 或 delete",
Self::InvalidStatus => "REVIEW_BAD_REQUEST: 状态须为 all、visible 或 hidden",
Self::InvalidReason => "REVIEW_VALIDATION: 原因去除首尾空白后须为 1–4000 字符",
})
}
}
pub fn normalize_review_moderation_reason(
action: &str,
reason: Option<&str>,
) -> Result<Option<String>, ReviewModerationValidationError> {
match action {
"restore" => Ok(None),
"hide" | "delete" => {
let reason = reason.unwrap_or("").trim();
if !(1..=4000).contains(&reason.chars().count()) {
return Err(ReviewModerationValidationError::InvalidReason);
}
Ok(Some(reason.to_string()))
}
_ => Err(ReviewModerationValidationError::InvalidAction),
}
}
pub fn validate_review_list_status(status: &str) -> Result<(), ReviewModerationValidationError> {
match status {
"all" | "visible" | "hidden" => Ok(()),
_ => Err(ReviewModerationValidationError::InvalidStatus),
}
}
pub fn review_matches_filters(
review_game_id: &str,
review_user_id: &str,
comment: &str,
is_hidden: bool,
game_id: Option<&str>,
user_id: Option<&str>,
keyword: Option<&str>,
status: &str,
) -> bool {
game_id.is_none_or(|value| value == review_game_id)
&& user_id.is_none_or(|value| value == review_user_id)
&& keyword.is_none_or(|value| comment.contains(value))
&& match status {
"all" => true,
"visible" => !is_hidden,
"hidden" => is_hidden,
_ => false,
}
}
pub fn review_moderation_operation_id(admin_user_id: &str, idempotency_key: &str) -> String {
format!("{}:{admin_user_id}{idempotency_key}", admin_user_id.len())
}
#[cfg(test)]
mod tests {
use super::*;
@@ -106,4 +180,122 @@ mod tests {
assert_eq!(review_order(1, "z", 2, "a"), Ordering::Greater);
assert_eq!(review_order(2, "b", 2, "a"), Ordering::Less);
}
#[test]
fn moderation_reason_and_action_follow_contract() {
for action in ["hide", "delete"] {
assert_eq!(
normalize_review_moderation_reason(action, None),
Err(ReviewModerationValidationError::InvalidReason)
);
assert_eq!(
normalize_review_moderation_reason(action, Some(" \n ")),
Err(ReviewModerationValidationError::InvalidReason)
);
assert_eq!(
normalize_review_moderation_reason(action, Some(" 原因😀 \n")),
Ok(Some("原因😀".into()))
);
assert!(normalize_review_moderation_reason(action, Some(&"😀".repeat(4000))).is_ok());
assert_eq!(
normalize_review_moderation_reason(action, Some(&"😀".repeat(4001))),
Err(ReviewModerationValidationError::InvalidReason)
);
}
assert_eq!(
normalize_review_moderation_reason("restore", None),
Ok(None)
);
assert_eq!(
normalize_review_moderation_reason("restore", Some("忽略")),
Ok(None)
);
assert_eq!(
normalize_review_moderation_reason("edit", Some("原因")),
Err(ReviewModerationValidationError::InvalidAction)
);
assert_ne!(
review_moderation_operation_id("a", "bc"),
review_moderation_operation_id("ab", "c")
);
assert_ne!(
review_moderation_operation_id("admin1", "key"),
review_moderation_operation_id("admin2", "key")
);
}
#[test]
fn review_filters_combine_exact_ids_case_sensitive_text_and_visibility() {
assert!(review_matches_filters(
"game1",
"user1",
"Text 中文",
true,
Some("game1"),
Some("user1"),
Some("Text"),
"hidden"
));
assert!(!review_matches_filters(
"game1",
"user1",
"Text 中文",
true,
Some("game1"),
Some("user1"),
Some("text"),
"hidden"
));
assert!(!review_matches_filters(
"game1",
"user1",
"Text",
true,
Some("game2"),
None,
None,
"all"
));
assert!(!review_matches_filters(
"game1",
"user1",
"",
false,
None,
None,
Some("Text"),
"visible"
));
assert!(!review_matches_filters(
"game1", "user1", "", true, None, None, None, "visible"
));
assert!(review_matches_filters(
"game1", "user1", "", false, None, None, None, "visible"
));
assert_eq!(validate_review_list_status("all"), Ok(()));
assert_eq!(
validate_review_list_status("published"),
Err(ReviewModerationValidationError::InvalidStatus)
);
}
#[test]
fn hidden_reviews_never_contribute_to_public_rating_summary() {
assert_eq!(
visible_review_summary([(10, true), (1, true)].into_iter()),
(None, 0)
);
assert_eq!(
visible_review_summary([(10, true), (1, false), (9, false)].into_iter()),
(Some(5.0), 2)
);
assert_eq!(
visible_review_summary([(1, true), (1, false), (9, false)].into_iter()),
(Some(5.0), 2)
);
assert_eq!(
visible_review_summary([(10, false), (1, false), (9, false)].into_iter()),
(Some(6.7), 3)
);
}
}
+162 -1
View File
@@ -10,7 +10,7 @@ use crate::creation_entry_config::{
};
/// 后台 member 可被授予的一级 Tab 权限;账号管理仅 owner 可见,不进入该集合。
pub const ADMIN_TAB_PERMISSIONS: [&str; 20] = [
pub const ADMIN_TAB_PERMISSIONS: [&str; 21] = [
"dashboard",
"overview",
"tables",
@@ -27,12 +27,124 @@ pub const ADMIN_TAB_PERMISSIONS: [&str; 20] = [
"editor-generation-pricing",
"editor-showcase",
"game-management",
"game-reviews",
"editor-assets",
"agc-templates",
"error-reports",
"project-snapshots",
];
/// 后台游戏评价的游戏选择查询,覆盖全部游戏可见状态。
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewGamesQuery {
pub query: Option<String>,
pub page: Option<u32>,
pub page_size: Option<u32>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewGame {
pub game_id: String,
pub title: String,
pub status: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewGamesResponse {
pub games: Vec<AdminGameReviewGame>,
pub page: u32,
pub page_size: u32,
pub total: u64,
pub total_pages: u64,
}
/// 用户 ID 精确匹配;关键词与其他条件由后端按 AND 组合筛选。
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewsQuery {
pub game_id: Option<String>,
pub user_id: Option<String>,
pub keyword: Option<String>,
pub status: Option<String>,
pub page: Option<u32>,
pub page_size: Option<u32>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewGameInfo {
pub title: String,
pub status: String,
}
/// 后台完整评价;管理原因只保存在后台操作记录,不进入普通用户投影。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReview {
pub id: String,
pub game_id: String,
pub game: AdminGameReviewGameInfo,
pub author: crate::game_distribution::GameDistributionAuthor,
pub score: i64,
pub comment: String,
pub is_hidden: bool,
pub created_at: String,
pub updated_at: String,
}
/// 管理操作记录不复制评论正文;删除后依旧保留目标身份与原创建时间。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewOperation {
pub id: String,
pub review_id: String,
pub game_id: String,
pub user_id: String,
pub review_created_at: String,
pub action: String,
pub admin_user_id: String,
pub reason: Option<String>,
pub created_at: String,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewsResponse {
pub reviews: Vec<AdminGameReview>,
pub page: u32,
pub page_size: u32,
pub total: u64,
pub total_pages: u64,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewDetailResponse {
pub review: AdminGameReview,
pub operations: Vec<AdminGameReviewOperation>,
}
/// 原创建时间保护删除后重新评价的实例;管理员身份来自会话。
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewModerationRequest {
pub action: String,
pub expected_created_at: String,
#[serde(default)]
pub reason: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminGameReviewModerationResponse {
pub review: Option<AdminGameReview>,
pub operation: AdminGameReviewOperation,
pub replayed: bool,
}
/// 私有工程快照的后台分页查询。
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -1298,6 +1410,55 @@ mod tests {
AdminUpdateAgcTemplateRequest,
};
#[test]
fn game_review_contract_uses_camel_case_and_nullable_operation_result() {
use super::{
AdminGameReviewModerationRequest, AdminGameReviewModerationResponse,
AdminGameReviewOperation,
};
let request: AdminGameReviewModerationRequest = serde_json::from_value(json!({
"action":"restore", "expectedCreatedAt":"2026-10-01T00:00:00Z",
}))
.unwrap();
assert!(request.reason.is_none());
assert_eq!(
serde_json::to_value(request).unwrap()["expectedCreatedAt"],
"2026-10-01T00:00:00Z"
);
for value in [
json!({"action":1,"expectedCreatedAt":"2026-10-01T00:00:00Z"}),
json!({"action":"restore","expectedCreatedAt":1}),
json!({"action":"hide","expectedCreatedAt":"2026-10-01T00:00:00Z","reason":123}),
] {
assert!(serde_json::from_value::<AdminGameReviewModerationRequest>(value).is_err());
}
let response = serde_json::to_value(AdminGameReviewModerationResponse {
review: None,
replayed: true,
operation: AdminGameReviewOperation {
id: "operation-1".into(),
review_id: "review-1".into(),
game_id: "game-1".into(),
user_id: "user-1".into(),
review_created_at: "2026-10-01T00:00:00Z".into(),
action: "restore".into(),
admin_user_id: "admin-1".into(),
reason: None,
created_at: "2026-10-01T00:00:01Z".into(),
},
})
.unwrap();
assert!(response["review"].is_null());
assert!(response["operation"]["reason"].is_null());
assert_eq!(
response["operation"]["reviewCreatedAt"],
"2026-10-01T00:00:00Z"
);
assert_eq!(response["operation"]["adminUserId"], "admin-1");
assert!(response["operation"].get("comment").is_none());
assert!(ADMIN_TAB_PERMISSIONS.contains(&"game-reviews"));
}
#[test]
fn agc_template_snapshot_uses_camel_case_and_assignable_tab_permission() {
let value = serde_json::to_value(AdminAgcTemplateListResponse {
@@ -98,6 +98,8 @@ pub struct GameDistributionReview {
pub author: GameDistributionAuthor,
pub score: i64,
pub comment: String,
#[serde(default)]
pub is_hidden: bool,
pub created_at: String,
pub updated_at: String,
}
@@ -22,14 +22,15 @@ mod error_reports;
pub mod external_api_key;
pub mod game_distribution;
pub use game_distribution::{
GameDistributionAdminGameListRecordInput, GameDistributionApproveRecordInput,
GameDistributionCancelVersionRecordInput, GameDistributionConfirmPackageRecordInput,
GameDistributionCreateGameRecordInput, GameDistributionCreateVersionRecordInput,
GameDistributionFailUploadRecordInput, GameDistributionGetGameRecordInput,
GameDistributionOwnerGameListRecordInput, GameDistributionPublicGameListRecordInput,
GameDistributionRejectRecordInput, GameDistributionRestoreRecordInput,
GameDistributionSubmitReviewRecordInput, GameDistributionSuspendRecordInput,
GameDistributionUnpublishRecordInput,
GameDistributionAdminGameListRecordInput, GameDistributionAdminUserReviewListRecordInput,
GameDistributionApproveRecordInput, GameDistributionCancelVersionRecordInput,
GameDistributionConfirmPackageRecordInput, GameDistributionCreateGameRecordInput,
GameDistributionCreateVersionRecordInput, GameDistributionFailUploadRecordInput,
GameDistributionGetGameRecordInput, GameDistributionOwnerGameListRecordInput,
GameDistributionPublicGameListRecordInput, GameDistributionRejectRecordInput,
GameDistributionRestoreRecordInput, GameDistributionReviewGameListRecordInput,
GameDistributionReviewModerationRecordInput, GameDistributionSubmitReviewRecordInput,
GameDistributionSuspendRecordInput, GameDistributionUnpublishRecordInput,
};
#[path = "active/external_generation.rs"]
pub mod external_generation;
@@ -92,9 +92,13 @@ pub use self::external_generation::{
ExternalGenerationQueueStatsRecord,
};
pub use self::game_distribution::{
GameDistributionAdminGameRecord, GameDistributionAdminVersionRecord,
GameDistributionGameRecord, GameDistributionOwnerGameRecord, GameDistributionPublicGameRecord,
GameDistributionRatingSummaryRecord, GameDistributionUserReviewListRecord,
GameDistributionAdminGameRecord, GameDistributionAdminUserReviewDetailRecord,
GameDistributionAdminUserReviewListRecord, GameDistributionAdminUserReviewRecord,
GameDistributionAdminVersionRecord, GameDistributionGameRecord,
GameDistributionOwnerGameRecord, GameDistributionPublicGameRecord,
GameDistributionRatingSummaryRecord, GameDistributionReviewGameListRecord,
GameDistributionReviewGameRecord, GameDistributionReviewModerationOperationRecord,
GameDistributionReviewModerationRecord, GameDistributionUserReviewListRecord,
GameDistributionUserReviewRecord, GameDistributionUserReviewSaveRecord,
GameDistributionVersionRecord,
};
@@ -151,11 +155,11 @@ pub(crate) use self::external_generation::{
map_external_generation_queue_stats_result,
};
pub(crate) use self::game_distribution::{
ensure_user_review_result, map_game_distribution_admin_game_list_result,
map_game_distribution_game_result, map_game_distribution_owner_game_list_result,
map_game_distribution_public_game_list_result, map_game_distribution_public_game_result,
map_game_distribution_review_list_result, map_game_distribution_version_result,
map_user_review,
ensure_admin_user_review_result, ensure_user_review_result, map_admin_user_review,
map_game_distribution_admin_game_list_result, map_game_distribution_game_result,
map_game_distribution_owner_game_list_result, map_game_distribution_public_game_list_result,
map_game_distribution_public_game_result, map_game_distribution_review_list_result,
map_game_distribution_version_result, map_review_moderation_operation, map_user_review,
};
pub(crate) use self::runtime::{
map_feature_gate_config_procedure_result, map_runtime_setting_procedure_result,
@@ -11,6 +11,7 @@ pub struct GameDistributionUserReviewRecord {
pub comment: String,
pub created_at_micros: i64,
pub updated_at_micros: i64,
pub is_hidden: bool,
}
#[derive(Clone, Debug, PartialEq)]
@@ -35,6 +36,99 @@ pub struct GameDistributionUserReviewSaveRecord {
pub rating_summary: GameDistributionRatingSummaryRecord,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionAdminUserReviewRecord {
pub review: GameDistributionUserReviewRecord,
pub game_title: String,
pub game_status: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionReviewModerationOperationRecord {
pub operation_id: String,
pub review_id: String,
pub game_id: String,
pub user_id: String,
pub review_created_at_micros: i64,
pub action: String,
pub admin_user_id: String,
pub reason: Option<String>,
pub created_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionReviewGameRecord {
pub game_id: String,
pub title: String,
pub status: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionAdminUserReviewListRecord {
pub reviews: Vec<GameDistributionAdminUserReviewRecord>,
pub page: u32,
pub page_size: u32,
pub total: u64,
pub total_pages: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionReviewGameListRecord {
pub games: Vec<GameDistributionReviewGameRecord>,
pub page: u32,
pub page_size: u32,
pub total: u64,
pub total_pages: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionAdminUserReviewDetailRecord {
pub review: GameDistributionAdminUserReviewRecord,
pub operations: Vec<GameDistributionReviewModerationOperationRecord>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GameDistributionReviewModerationRecord {
pub review: Option<GameDistributionAdminUserReviewRecord>,
pub operation: GameDistributionReviewModerationOperationRecord,
pub replayed: bool,
}
pub(crate) fn map_admin_user_review(
snapshot: crate::module_bindings::GameDistributionAdminUserReviewSnapshot,
) -> GameDistributionAdminUserReviewRecord {
GameDistributionAdminUserReviewRecord {
review: map_user_review(snapshot.review),
game_title: snapshot.game_title,
game_status: snapshot.game_status,
}
}
pub(crate) fn map_review_moderation_operation(
snapshot: crate::module_bindings::GameDistributionReviewModerationOperationSnapshot,
) -> GameDistributionReviewModerationOperationRecord {
GameDistributionReviewModerationOperationRecord {
operation_id: snapshot.operation_id,
review_id: snapshot.review_id,
game_id: snapshot.game_id,
user_id: snapshot.user_id,
review_created_at_micros: snapshot.review_created_at_micros,
action: snapshot.action,
admin_user_id: snapshot.admin_user_id,
reason: snapshot.reason,
created_at_micros: snapshot.created_at_micros,
}
}
pub(crate) fn ensure_admin_user_review_result(
result: crate::module_bindings::GameDistributionAdminUserReviewResult,
) -> Result<crate::module_bindings::GameDistributionAdminUserReviewResult, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
Ok(result)
}
pub(crate) fn map_user_review(
snapshot: crate::module_bindings::GameDistributionUserReviewSnapshot,
) -> GameDistributionUserReviewRecord {
@@ -48,6 +142,7 @@ pub(crate) fn map_user_review(
comment: snapshot.comment,
created_at_micros: snapshot.created_at_micros,
updated_at_micros: snapshot.updated_at_micros,
is_hidden: snapshot.is_hidden,
}
}
@@ -1,5 +1,32 @@
use super::*;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GameDistributionAdminUserReviewListRecordInput {
pub game_id: Option<String>,
pub user_id: Option<String>,
pub keyword: Option<String>,
pub status: String,
pub page: u32,
pub page_size: u32,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GameDistributionReviewGameListRecordInput {
pub query: Option<String>,
pub page: u32,
pub page_size: u32,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GameDistributionReviewModerationRecordInput {
pub review_id: String,
pub admin_user_id: String,
pub action: String,
pub idempotency_key: String,
pub expected_created_at_micros: i64,
pub reason: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GameDistributionPublicGameListRecordInput {
pub search: Option<String>,
@@ -165,6 +192,173 @@ pub struct GameDistributionSuspendRecordInput {
}
impl SpacetimeClient {
pub async fn list_admin_game_distribution_user_reviews(
&self,
input: GameDistributionAdminUserReviewListRecordInput,
) -> Result<GameDistributionAdminUserReviewListRecord, SpacetimeClientError> {
let input = crate::module_bindings::GameDistributionAdminUserReviewListInput {
game_id: input.game_id,
user_id: input.user_id,
keyword: input.keyword,
status: input.status,
page: input.page,
page_size: input.page_size,
};
self.call_after_connect(
"list_admin_game_distribution_user_reviews",
move |connection, sender| {
connection
.procedures()
.list_admin_game_distribution_user_reviews_and_return_then(
input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(ensure_admin_user_review_result)
.map(|result| GameDistributionAdminUserReviewListRecord {
reviews: result
.reviews
.into_iter()
.map(map_admin_user_review)
.collect(),
page: result.page,
page_size: result.page_size,
total: result.total,
total_pages: result.total_pages,
});
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn list_game_distribution_review_games(
&self,
input: GameDistributionReviewGameListRecordInput,
) -> Result<GameDistributionReviewGameListRecord, SpacetimeClientError> {
let input = crate::module_bindings::GameDistributionReviewGameListInput {
query: input.query,
page: input.page,
page_size: input.page_size,
};
self.call_after_connect(
"list_game_distribution_review_games",
move |connection, sender| {
connection
.procedures()
.list_game_distribution_review_games_and_return_then(
input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(ensure_admin_user_review_result)
.map(|result| GameDistributionReviewGameListRecord {
games: result
.games
.into_iter()
.map(|game| GameDistributionReviewGameRecord {
game_id: game.game_id,
title: game.title,
status: game.status,
})
.collect(),
page: result.page,
page_size: result.page_size,
total: result.total,
total_pages: result.total_pages,
});
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn get_admin_game_distribution_user_review(
&self,
review_id: String,
) -> Result<GameDistributionAdminUserReviewDetailRecord, SpacetimeClientError> {
let input = crate::module_bindings::GameDistributionAdminUserReviewInput { review_id };
self.call_after_connect(
"get_admin_game_distribution_user_review",
move |connection, sender| {
connection
.procedures()
.get_admin_game_distribution_user_review_and_return_then(
input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(ensure_admin_user_review_result)
.and_then(|result| {
let review = result.review.ok_or_else(|| {
SpacetimeClientError::procedure_failed(Some(
"REVIEW_NOT_FOUND: 评价不存在".into(),
))
})?;
Ok(GameDistributionAdminUserReviewDetailRecord {
review: map_admin_user_review(review),
operations: result
.operations
.into_iter()
.map(map_review_moderation_operation)
.collect(),
})
});
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn moderate_game_distribution_user_review(
&self,
input: GameDistributionReviewModerationRecordInput,
) -> Result<GameDistributionReviewModerationRecord, SpacetimeClientError> {
let input = crate::module_bindings::GameDistributionReviewModerationInput {
review_id: input.review_id,
admin_user_id: input.admin_user_id,
action: input.action,
idempotency_key: input.idempotency_key,
expected_created_at_micros: input.expected_created_at_micros,
reason: input.reason,
};
self.call_after_connect(
"moderate_game_distribution_user_review",
move |connection, sender| {
connection
.procedures()
.moderate_game_distribution_user_review_and_return_then(
input,
move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(ensure_admin_user_review_result)
.and_then(|result| {
let operation = result.operation.ok_or_else(|| {
SpacetimeClientError::procedure_failed(Some(
"管理操作缺少结果".into(),
))
})?;
Ok(GameDistributionReviewModerationRecord {
review: result.review.map(map_admin_user_review),
operation: map_review_moderation_operation(operation),
replayed: result.replayed,
})
});
send_once(&sender, mapped);
},
);
},
)
.await
}
pub async fn list_game_distribution_user_reviews(
&self,
game_id: String,
@@ -401,6 +401,10 @@ pub mod find_editor_asset_group_source_and_return_procedure;
pub mod game_distribution_admin_game_list_input_type;
pub mod game_distribution_admin_game_list_result_type;
pub mod game_distribution_admin_game_snapshot_type;
pub mod game_distribution_admin_user_review_input_type;
pub mod game_distribution_admin_user_review_list_input_type;
pub mod game_distribution_admin_user_review_result_type;
pub mod game_distribution_admin_user_review_snapshot_type;
pub mod game_distribution_admin_version_snapshot_type;
pub mod game_distribution_approve_input_type;
pub mod game_distribution_cancel_version_input_type;
@@ -427,7 +431,13 @@ pub mod game_distribution_public_game_list_input_type;
pub mod game_distribution_public_game_snapshot_type;
pub mod game_distribution_reject_input_type;
pub mod game_distribution_restore_input_type;
pub mod game_distribution_review_game_list_input_type;
pub mod game_distribution_review_game_snapshot_type;
pub mod game_distribution_review_list_input_type;
pub mod game_distribution_review_moderation_input_type;
pub mod game_distribution_review_moderation_log_table;
pub mod game_distribution_review_moderation_log_type;
pub mod game_distribution_review_moderation_operation_snapshot_type;
pub mod game_distribution_review_table;
pub mod game_distribution_review_type;
pub mod game_distribution_submit_review_input_type;
@@ -445,6 +455,7 @@ pub mod game_distribution_version_type;
pub mod get_admin_account_by_id_and_return_procedure;
pub mod get_admin_account_by_username_and_return_procedure;
pub mod get_admin_dashboard_stats_and_return_procedure;
pub mod get_admin_game_distribution_user_review_and_return_procedure;
pub mod get_asset_object_by_id_and_return_procedure;
pub mod get_asset_object_by_location_and_return_procedure;
pub mod get_asset_read_access_by_location_and_return_procedure;
@@ -482,6 +493,7 @@ pub mod import_database_migration_incremental_from_file_procedure;
pub mod initialize_editor_generation_pricing_config_if_missing_and_return_procedure;
pub mod list_admin_accounts_and_return_procedure;
pub mod list_admin_game_distribution_games_and_return_procedure;
pub mod list_admin_game_distribution_user_reviews_and_return_procedure;
pub mod list_agc_tracking_events_procedure;
pub mod list_asset_history_and_return_procedure;
pub mod list_editor_agent_conversations_and_return_procedure;
@@ -491,6 +503,7 @@ pub mod list_external_api_keys_and_return_procedure;
pub mod list_external_generation_job_summaries_and_return_procedure;
pub mod list_external_generation_jobs_and_return_procedure;
pub mod list_game_distribution_games_and_return_procedure;
pub mod list_game_distribution_review_games_and_return_procedure;
pub mod list_game_distribution_reviews_and_return_procedure;
pub mod list_game_distribution_user_reviews_and_return_procedure;
pub mod list_owner_game_distribution_games_and_return_procedure;
@@ -515,6 +528,7 @@ pub mod llm_router_quota_settlement_result_type;
pub mod mark_editor_showcase_asset_refunded_and_return_procedure;
pub mod mark_profile_recharge_order_expiration_checked_procedure;
pub mod mark_profile_recharge_order_paid_and_return_procedure;
pub mod moderate_game_distribution_user_review_and_return_procedure;
pub mod normalize_editor_character_animation_metadata_and_return_procedure;
pub mod persist_editor_generation_result_and_return_procedure;
pub mod persist_editor_pixel_art_result_and_return_procedure;
@@ -1188,6 +1202,10 @@ pub use find_editor_asset_group_source_and_return_procedure::find_editor_asset_g
pub use game_distribution_admin_game_list_input_type::GameDistributionAdminGameListInput;
pub use game_distribution_admin_game_list_result_type::GameDistributionAdminGameListResult;
pub use game_distribution_admin_game_snapshot_type::GameDistributionAdminGameSnapshot;
pub use game_distribution_admin_user_review_input_type::GameDistributionAdminUserReviewInput;
pub use game_distribution_admin_user_review_list_input_type::GameDistributionAdminUserReviewListInput;
pub use game_distribution_admin_user_review_result_type::GameDistributionAdminUserReviewResult;
pub use game_distribution_admin_user_review_snapshot_type::GameDistributionAdminUserReviewSnapshot;
pub use game_distribution_admin_version_snapshot_type::GameDistributionAdminVersionSnapshot;
pub use game_distribution_approve_input_type::GameDistributionApproveInput;
pub use game_distribution_cancel_version_input_type::GameDistributionCancelVersionInput;
@@ -1214,7 +1232,13 @@ pub use game_distribution_public_game_list_input_type::GameDistributionPublicGam
pub use game_distribution_public_game_snapshot_type::GameDistributionPublicGameSnapshot;
pub use game_distribution_reject_input_type::GameDistributionRejectInput;
pub use game_distribution_restore_input_type::GameDistributionRestoreInput;
pub use game_distribution_review_game_list_input_type::GameDistributionReviewGameListInput;
pub use game_distribution_review_game_snapshot_type::GameDistributionReviewGameSnapshot;
pub use game_distribution_review_list_input_type::GameDistributionReviewListInput;
pub use game_distribution_review_moderation_input_type::GameDistributionReviewModerationInput;
pub use game_distribution_review_moderation_log_table::*;
pub use game_distribution_review_moderation_log_type::GameDistributionReviewModerationLog;
pub use game_distribution_review_moderation_operation_snapshot_type::GameDistributionReviewModerationOperationSnapshot;
pub use game_distribution_review_table::*;
pub use game_distribution_review_type::GameDistributionReview;
pub use game_distribution_submit_review_input_type::GameDistributionSubmitReviewInput;
@@ -1232,6 +1256,7 @@ pub use game_distribution_version_type::GameDistributionVersion;
pub use get_admin_account_by_id_and_return_procedure::get_admin_account_by_id_and_return;
pub use get_admin_account_by_username_and_return_procedure::get_admin_account_by_username_and_return;
pub use get_admin_dashboard_stats_and_return_procedure::get_admin_dashboard_stats_and_return;
pub use get_admin_game_distribution_user_review_and_return_procedure::get_admin_game_distribution_user_review_and_return;
pub use get_asset_object_by_id_and_return_procedure::get_asset_object_by_id_and_return;
pub use get_asset_object_by_location_and_return_procedure::get_asset_object_by_location_and_return;
pub use get_asset_read_access_by_location_and_return_procedure::get_asset_read_access_by_location_and_return;
@@ -1269,6 +1294,7 @@ pub use import_database_migration_incremental_from_file_procedure::import_databa
pub use initialize_editor_generation_pricing_config_if_missing_and_return_procedure::initialize_editor_generation_pricing_config_if_missing_and_return;
pub use list_admin_accounts_and_return_procedure::list_admin_accounts_and_return;
pub use list_admin_game_distribution_games_and_return_procedure::list_admin_game_distribution_games_and_return;
pub use list_admin_game_distribution_user_reviews_and_return_procedure::list_admin_game_distribution_user_reviews_and_return;
pub use list_agc_tracking_events_procedure::list_agc_tracking_events;
pub use list_asset_history_and_return_procedure::list_asset_history_and_return;
pub use list_editor_agent_conversations_and_return_procedure::list_editor_agent_conversations_and_return;
@@ -1278,6 +1304,7 @@ pub use list_external_api_keys_and_return_procedure::list_external_api_keys_and_
pub use list_external_generation_job_summaries_and_return_procedure::list_external_generation_job_summaries_and_return;
pub use list_external_generation_jobs_and_return_procedure::list_external_generation_jobs_and_return;
pub use list_game_distribution_games_and_return_procedure::list_game_distribution_games_and_return;
pub use list_game_distribution_review_games_and_return_procedure::list_game_distribution_review_games_and_return;
pub use list_game_distribution_reviews_and_return_procedure::list_game_distribution_reviews_and_return;
pub use list_game_distribution_user_reviews_and_return_procedure::list_game_distribution_user_reviews_and_return;
pub use list_owner_game_distribution_games_and_return_procedure::list_owner_game_distribution_games_and_return;
@@ -1302,6 +1329,7 @@ pub use llm_router_quota_settlement_result_type::LlmRouterQuotaSettlementResult;
pub use mark_editor_showcase_asset_refunded_and_return_procedure::mark_editor_showcase_asset_refunded_and_return;
pub use mark_profile_recharge_order_expiration_checked_procedure::mark_profile_recharge_order_expiration_checked;
pub use mark_profile_recharge_order_paid_and_return_procedure::mark_profile_recharge_order_paid_and_return;
pub use moderate_game_distribution_user_review_and_return_procedure::moderate_game_distribution_user_review_and_return;
pub use normalize_editor_character_animation_metadata_and_return_procedure::normalize_editor_character_animation_metadata_and_return;
pub use persist_editor_generation_result_and_return_procedure::persist_editor_generation_result_and_return;
pub use persist_editor_pixel_art_result_and_return_procedure::persist_editor_pixel_art_result_and_return;
@@ -1735,6 +1763,8 @@ pub struct DbUpdate {
game_distribution_game: __sdk::TableUpdate<GameDistributionGame>,
game_distribution_idempotency_receipt: __sdk::TableUpdate<GameDistributionIdempotencyReceipt>,
game_distribution_review: __sdk::TableUpdate<GameDistributionReview>,
game_distribution_review_moderation_log:
__sdk::TableUpdate<GameDistributionReviewModerationLog>,
game_distribution_version: __sdk::TableUpdate<GameDistributionVersion>,
llm_router_account: __sdk::TableUpdate<LlmRouterAccount>,
llm_router_billing_checkpoint: __sdk::TableUpdate<LlmRouterBillingCheckpoint>,
@@ -1953,6 +1983,13 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
"game_distribution_review" => db_update.game_distribution_review.append(
game_distribution_review_table::parse_table_update(table_update)?,
),
"game_distribution_review_moderation_log" => {
db_update.game_distribution_review_moderation_log.append(
game_distribution_review_moderation_log_table::parse_table_update(
table_update,
)?,
)
}
"game_distribution_version" => db_update.game_distribution_version.append(
game_distribution_version_table::parse_table_update(table_update)?,
),
@@ -2352,6 +2389,12 @@ impl __sdk::DbUpdate for DbUpdate {
&self.game_distribution_review,
)
.with_updates_by_pk(|row| &row.review_id);
diff.game_distribution_review_moderation_log = cache
.apply_diff_to_table::<GameDistributionReviewModerationLog>(
"game_distribution_review_moderation_log",
&self.game_distribution_review_moderation_log,
)
.with_updates_by_pk(|row| &row.operation_id);
diff.game_distribution_version = cache
.apply_diff_to_table::<GameDistributionVersion>(
"game_distribution_version",
@@ -2716,6 +2759,9 @@ impl __sdk::DbUpdate for DbUpdate {
"game_distribution_review" => db_update
.game_distribution_review
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"game_distribution_review_moderation_log" => db_update
.game_distribution_review_moderation_log
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"game_distribution_version" => db_update
.game_distribution_version
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
@@ -2987,6 +3033,9 @@ impl __sdk::DbUpdate for DbUpdate {
"game_distribution_review" => db_update
.game_distribution_review
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"game_distribution_review_moderation_log" => db_update
.game_distribution_review_moderation_log
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"game_distribution_version" => db_update
.game_distribution_version
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
@@ -3171,6 +3220,8 @@ pub struct AppliedDiff<'r> {
game_distribution_idempotency_receipt:
__sdk::TableAppliedDiff<'r, GameDistributionIdempotencyReceipt>,
game_distribution_review: __sdk::TableAppliedDiff<'r, GameDistributionReview>,
game_distribution_review_moderation_log:
__sdk::TableAppliedDiff<'r, GameDistributionReviewModerationLog>,
game_distribution_version: __sdk::TableAppliedDiff<'r, GameDistributionVersion>,
llm_router_account: __sdk::TableAppliedDiff<'r, LlmRouterAccount>,
llm_router_billing_checkpoint: __sdk::TableAppliedDiff<'r, LlmRouterBillingCheckpoint>,
@@ -3451,6 +3502,11 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
&self.game_distribution_review,
event,
);
callbacks.invoke_table_row_callbacks::<GameDistributionReviewModerationLog>(
"game_distribution_review_moderation_log",
&self.game_distribution_review_moderation_log,
event,
);
callbacks.invoke_table_row_callbacks::<GameDistributionVersion>(
"game_distribution_version",
&self.game_distribution_version,
@@ -4357,6 +4413,7 @@ impl __sdk::SpacetimeModule for RemoteModule {
game_distribution_game_table::register_table(client_cache);
game_distribution_idempotency_receipt_table::register_table(client_cache);
game_distribution_review_table::register_table(client_cache);
game_distribution_review_moderation_log_table::register_table(client_cache);
game_distribution_version_table::register_table(client_cache);
llm_router_account_table::register_table(client_cache);
llm_router_billing_checkpoint_table::register_table(client_cache);
@@ -4445,6 +4502,7 @@ impl __sdk::SpacetimeModule for RemoteModule {
"game_distribution_game",
"game_distribution_idempotency_receipt",
"game_distribution_review",
"game_distribution_review_moderation_log",
"game_distribution_version",
"llm_router_account",
"llm_router_billing_checkpoint",
@@ -0,0 +1,15 @@
// 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)]
pub struct GameDistributionAdminUserReviewInput {
pub review_id: String,
}
impl __sdk::InModule for GameDistributionAdminUserReviewInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,20 @@
// 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)]
pub struct GameDistributionAdminUserReviewListInput {
pub game_id: Option<String>,
pub user_id: Option<String>,
pub keyword: Option<String>,
pub status: String,
pub page: u32,
pub page_size: u32,
}
impl __sdk::InModule for GameDistributionAdminUserReviewListInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,30 @@
// 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};
use super::game_distribution_admin_user_review_snapshot_type::GameDistributionAdminUserReviewSnapshot;
use super::game_distribution_review_game_snapshot_type::GameDistributionReviewGameSnapshot;
use super::game_distribution_review_moderation_operation_snapshot_type::GameDistributionReviewModerationOperationSnapshot;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct GameDistributionAdminUserReviewResult {
pub ok: bool,
pub reviews: Vec<GameDistributionAdminUserReviewSnapshot>,
pub games: Vec<GameDistributionReviewGameSnapshot>,
pub review: Option<GameDistributionAdminUserReviewSnapshot>,
pub operations: Vec<GameDistributionReviewModerationOperationSnapshot>,
pub operation: Option<GameDistributionReviewModerationOperationSnapshot>,
pub page: u32,
pub page_size: u32,
pub total: u64,
pub total_pages: u64,
pub replayed: bool,
pub error_message: Option<String>,
}
impl __sdk::InModule for GameDistributionAdminUserReviewResult {
type Module = super::RemoteModule;
}
@@ -0,0 +1,19 @@
// 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};
use super::game_distribution_user_review_snapshot_type::GameDistributionUserReviewSnapshot;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct GameDistributionAdminUserReviewSnapshot {
pub review: GameDistributionUserReviewSnapshot,
pub game_title: String,
pub game_status: String,
}
impl __sdk::InModule for GameDistributionAdminUserReviewSnapshot {
type Module = super::RemoteModule;
}
@@ -0,0 +1,17 @@
// 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)]
pub struct GameDistributionReviewGameListInput {
pub query: Option<String>,
pub page: u32,
pub page_size: u32,
}
impl __sdk::InModule for GameDistributionReviewGameListInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,17 @@
// 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)]
pub struct GameDistributionReviewGameSnapshot {
pub game_id: String,
pub title: String,
pub status: String,
}
impl __sdk::InModule for GameDistributionReviewGameSnapshot {
type Module = super::RemoteModule;
}
@@ -0,0 +1,20 @@
// 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)]
pub struct GameDistributionReviewModerationInput {
pub review_id: String,
pub admin_user_id: String,
pub action: String,
pub idempotency_key: String,
pub expected_created_at_micros: i64,
pub reason: Option<String>,
}
impl __sdk::InModule for GameDistributionReviewModerationInput {
type Module = super::RemoteModule;
}
@@ -0,0 +1,245 @@
// 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 super::game_distribution_review_moderation_log_type::GameDistributionReviewModerationLog;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `game_distribution_review_moderation_log`.
///
/// Obtain a handle from the [`GameDistributionReviewModerationLogTableAccess::game_distribution_review_moderation_log`] method on [`super::RemoteTables`],
/// like `ctx.db.game_distribution_review_moderation_log()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.game_distribution_review_moderation_log().on_insert(...)`.
pub struct GameDistributionReviewModerationLogTableHandle<'ctx> {
imp: __sdk::TableHandle<GameDistributionReviewModerationLog>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
/// Lifetime-aware accessor marker for the table `game_distribution_review_moderation_log`.
pub struct GameDistributionReviewModerationLogTableAccessor;
impl __sdk::TableAccessor<super::RemoteTables>
for GameDistributionReviewModerationLogTableAccessor
{
type Row = GameDistributionReviewModerationLog;
type Handle<'db> = GameDistributionReviewModerationLogTableHandle<'db>;
fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> {
db.game_distribution_review_moderation_log()
}
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `game_distribution_review_moderation_log`.
///
/// Implemented for [`super::RemoteTables`].
pub trait GameDistributionReviewModerationLogTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`GameDistributionReviewModerationLogTableHandle`], which mediates access to the table `game_distribution_review_moderation_log`.
fn game_distribution_review_moderation_log(
&self,
) -> GameDistributionReviewModerationLogTableHandle<'_>;
}
impl GameDistributionReviewModerationLogTableAccess for super::RemoteTables {
fn game_distribution_review_moderation_log(
&self,
) -> GameDistributionReviewModerationLogTableHandle<'_> {
GameDistributionReviewModerationLogTableHandle {
imp: self.imp.get_table::<GameDistributionReviewModerationLog>(
"game_distribution_review_moderation_log",
),
ctx: std::marker::PhantomData,
}
}
}
pub struct GameDistributionReviewModerationLogInsertCallbackId(__sdk::CallbackId);
pub struct GameDistributionReviewModerationLogDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableLike for GameDistributionReviewModerationLogTableHandle<'ctx> {
type Row = GameDistributionReviewModerationLog;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = GameDistributionReviewModerationLog> + '_ {
self.imp.iter()
}
}
impl<'ctx> __sdk::Table for GameDistributionReviewModerationLogTableHandle<'ctx> {
type Row = GameDistributionReviewModerationLog;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = GameDistributionReviewModerationLog> + '_ {
self.imp.iter()
}
type InsertCallbackId = GameDistributionReviewModerationLogInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> GameDistributionReviewModerationLogInsertCallbackId {
GameDistributionReviewModerationLogInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: GameDistributionReviewModerationLogInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = GameDistributionReviewModerationLogDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> GameDistributionReviewModerationLogDeleteCallbackId {
GameDistributionReviewModerationLogDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: GameDistributionReviewModerationLogDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
impl<'ctx> __sdk::WithInsert for GameDistributionReviewModerationLogTableHandle<'ctx> {
type InsertCallbackId = GameDistributionReviewModerationLogInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> GameDistributionReviewModerationLogInsertCallbackId {
GameDistributionReviewModerationLogInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: GameDistributionReviewModerationLogInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
}
impl<'ctx> __sdk::WithDelete for GameDistributionReviewModerationLogTableHandle<'ctx> {
type DeleteCallbackId = GameDistributionReviewModerationLogDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> GameDistributionReviewModerationLogDeleteCallbackId {
GameDistributionReviewModerationLogDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: GameDistributionReviewModerationLogDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct GameDistributionReviewModerationLogUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for GameDistributionReviewModerationLogTableHandle<'ctx> {
type UpdateCallbackId = GameDistributionReviewModerationLogUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> GameDistributionReviewModerationLogUpdateCallbackId {
GameDistributionReviewModerationLogUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: GameDistributionReviewModerationLogUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
impl<'ctx> __sdk::WithUpdate for GameDistributionReviewModerationLogTableHandle<'ctx> {
type UpdateCallbackId = GameDistributionReviewModerationLogUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> GameDistributionReviewModerationLogUpdateCallbackId {
GameDistributionReviewModerationLogUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: GameDistributionReviewModerationLogUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `operation_id` unique index on the table `game_distribution_review_moderation_log`,
/// which allows point queries on the field of the same name
/// via the [`GameDistributionReviewModerationLogOperationIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.game_distribution_review_moderation_log().operation_id().find(...)`.
pub struct GameDistributionReviewModerationLogOperationIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<GameDistributionReviewModerationLog, String>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> GameDistributionReviewModerationLogTableHandle<'ctx> {
/// Get a handle on the `operation_id` unique index on the table `game_distribution_review_moderation_log`.
pub fn operation_id(&self) -> GameDistributionReviewModerationLogOperationIdUnique<'ctx> {
GameDistributionReviewModerationLogOperationIdUnique {
imp: self.imp.get_unique_constraint::<String>("operation_id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> GameDistributionReviewModerationLogOperationIdUnique<'ctx> {
/// Find the subscribed row whose `operation_id` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &String) -> Option<GameDistributionReviewModerationLog> {
self.imp.find(col_val)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<GameDistributionReviewModerationLog>(
"game_distribution_review_moderation_log",
);
_table.add_unique_constraint::<String>("operation_id", |row| &row.operation_id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<GameDistributionReviewModerationLog>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse(
"TableUpdate<GameDistributionReviewModerationLog>",
"TableUpdate",
)
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `GameDistributionReviewModerationLog`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait game_distribution_review_moderation_logQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `GameDistributionReviewModerationLog`.
fn game_distribution_review_moderation_log(
&self,
) -> __sdk::__query_builder::Table<GameDistributionReviewModerationLog>;
}
impl game_distribution_review_moderation_logQueryTableAccess for __sdk::QueryTableAccessor {
fn game_distribution_review_moderation_log(
&self,
) -> __sdk::__query_builder::Table<GameDistributionReviewModerationLog> {
__sdk::__query_builder::Table::new("game_distribution_review_moderation_log")
}
}
@@ -0,0 +1,77 @@
// 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)]
pub struct GameDistributionReviewModerationLog {
pub operation_id: String,
pub review_id: String,
pub game_id: String,
pub user_id: String,
pub review_created_at: __sdk::Timestamp,
pub action: String,
pub admin_user_id: String,
pub reason: Option<String>,
pub created_at: __sdk::Timestamp,
}
impl __sdk::InModule for GameDistributionReviewModerationLog {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `GameDistributionReviewModerationLog`.
///
/// Provides typed access to columns for query building.
pub struct GameDistributionReviewModerationLogCols {
pub operation_id: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, String>,
pub review_id: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, String>,
pub game_id: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, String>,
pub user_id: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, String>,
pub review_created_at:
__sdk::__query_builder::Col<GameDistributionReviewModerationLog, __sdk::Timestamp>,
pub action: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, String>,
pub admin_user_id: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, String>,
pub reason: __sdk::__query_builder::Col<GameDistributionReviewModerationLog, Option<String>>,
pub created_at:
__sdk::__query_builder::Col<GameDistributionReviewModerationLog, __sdk::Timestamp>,
}
impl __sdk::__query_builder::HasCols for GameDistributionReviewModerationLog {
type Cols = GameDistributionReviewModerationLogCols;
fn cols(table_name: &'static str) -> Self::Cols {
GameDistributionReviewModerationLogCols {
operation_id: __sdk::__query_builder::Col::new(table_name, "operation_id"),
review_id: __sdk::__query_builder::Col::new(table_name, "review_id"),
game_id: __sdk::__query_builder::Col::new(table_name, "game_id"),
user_id: __sdk::__query_builder::Col::new(table_name, "user_id"),
review_created_at: __sdk::__query_builder::Col::new(table_name, "review_created_at"),
action: __sdk::__query_builder::Col::new(table_name, "action"),
admin_user_id: __sdk::__query_builder::Col::new(table_name, "admin_user_id"),
reason: __sdk::__query_builder::Col::new(table_name, "reason"),
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
}
}
}
/// Indexed column accessor struct for the table `GameDistributionReviewModerationLog`.
///
/// Provides typed access to indexed columns for query building.
pub struct GameDistributionReviewModerationLogIxCols {
pub operation_id: __sdk::__query_builder::IxCol<GameDistributionReviewModerationLog, String>,
pub review_id: __sdk::__query_builder::IxCol<GameDistributionReviewModerationLog, String>,
}
impl __sdk::__query_builder::HasIxCols for GameDistributionReviewModerationLog {
type IxCols = GameDistributionReviewModerationLogIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
GameDistributionReviewModerationLogIxCols {
operation_id: __sdk::__query_builder::IxCol::new(table_name, "operation_id"),
review_id: __sdk::__query_builder::IxCol::new(table_name, "review_id"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for GameDistributionReviewModerationLog {}
@@ -0,0 +1,23 @@
// 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)]
pub struct GameDistributionReviewModerationOperationSnapshot {
pub operation_id: String,
pub review_id: String,
pub game_id: String,
pub user_id: String,
pub review_created_at_micros: i64,
pub action: String,
pub admin_user_id: String,
pub reason: Option<String>,
pub created_at_micros: i64,
}
impl __sdk::InModule for GameDistributionReviewModerationOperationSnapshot {
type Module = super::RemoteModule;
}
@@ -14,6 +14,7 @@ pub struct GameDistributionReview {
pub comment: String,
pub created_at: __sdk::Timestamp,
pub updated_at: __sdk::Timestamp,
pub is_hidden: bool,
}
impl __sdk::InModule for GameDistributionReview {
@@ -31,6 +32,7 @@ pub struct GameDistributionReviewCols {
pub comment: __sdk::__query_builder::Col<GameDistributionReview, String>,
pub created_at: __sdk::__query_builder::Col<GameDistributionReview, __sdk::Timestamp>,
pub updated_at: __sdk::__query_builder::Col<GameDistributionReview, __sdk::Timestamp>,
pub is_hidden: __sdk::__query_builder::Col<GameDistributionReview, bool>,
}
impl __sdk::__query_builder::HasCols for GameDistributionReview {
@@ -44,6 +46,7 @@ impl __sdk::__query_builder::HasCols for GameDistributionReview {
comment: __sdk::__query_builder::Col::new(table_name, "comment"),
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
is_hidden: __sdk::__query_builder::Col::new(table_name, "is_hidden"),
}
}
}
@@ -54,6 +57,7 @@ impl __sdk::__query_builder::HasCols for GameDistributionReview {
pub struct GameDistributionReviewIxCols {
pub game_id: __sdk::__query_builder::IxCol<GameDistributionReview, String>,
pub review_id: __sdk::__query_builder::IxCol<GameDistributionReview, String>,
pub user_id: __sdk::__query_builder::IxCol<GameDistributionReview, String>,
}
impl __sdk::__query_builder::HasIxCols for GameDistributionReview {
@@ -62,6 +66,7 @@ impl __sdk::__query_builder::HasIxCols for GameDistributionReview {
GameDistributionReviewIxCols {
game_id: __sdk::__query_builder::IxCol::new(table_name, "game_id"),
review_id: __sdk::__query_builder::IxCol::new(table_name, "review_id"),
user_id: __sdk::__query_builder::IxCol::new(table_name, "user_id"),
}
}
}
@@ -16,6 +16,7 @@ pub struct GameDistributionUserReviewSnapshot {
pub comment: String,
pub created_at_micros: i64,
pub updated_at_micros: i64,
pub is_hidden: bool,
}
impl __sdk::InModule for GameDistributionUserReviewSnapshot {
@@ -0,0 +1,62 @@
// 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};
use super::game_distribution_admin_user_review_input_type::GameDistributionAdminUserReviewInput;
use super::game_distribution_admin_user_review_result_type::GameDistributionAdminUserReviewResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct GetAdminGameDistributionUserReviewAndReturnArgs {
pub input: GameDistributionAdminUserReviewInput,
}
impl __sdk::InModule for GetAdminGameDistributionUserReviewAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `get_admin_game_distribution_user_review_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait get_admin_game_distribution_user_review_and_return {
fn get_admin_game_distribution_user_review_and_return(
&self,
input: GameDistributionAdminUserReviewInput,
) {
self.get_admin_game_distribution_user_review_and_return_then(input, |_, _| {});
}
fn get_admin_game_distribution_user_review_and_return_then(
&self,
input: GameDistributionAdminUserReviewInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<GameDistributionAdminUserReviewResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl get_admin_game_distribution_user_review_and_return for super::RemoteProcedures {
fn get_admin_game_distribution_user_review_and_return_then(
&self,
input: GameDistributionAdminUserReviewInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<GameDistributionAdminUserReviewResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, GameDistributionAdminUserReviewResult>(
"get_admin_game_distribution_user_review_and_return",
GetAdminGameDistributionUserReviewAndReturnArgs { input },
__callback,
);
}
}
@@ -0,0 +1,62 @@
// 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};
use super::game_distribution_admin_user_review_list_input_type::GameDistributionAdminUserReviewListInput;
use super::game_distribution_admin_user_review_result_type::GameDistributionAdminUserReviewResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct ListAdminGameDistributionUserReviewsAndReturnArgs {
pub input: GameDistributionAdminUserReviewListInput,
}
impl __sdk::InModule for ListAdminGameDistributionUserReviewsAndReturnArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `list_admin_game_distribution_user_reviews_and_return`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait list_admin_game_distribution_user_reviews_and_return {
fn list_admin_game_distribution_user_reviews_and_return(
&self,
input: GameDistributionAdminUserReviewListInput,
) {
self.list_admin_game_distribution_user_reviews_and_return_then(input, |_, _| {});
}
fn list_admin_game_distribution_user_reviews_and_return_then(
&self,
input: GameDistributionAdminUserReviewListInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<GameDistributionAdminUserReviewResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl list_admin_game_distribution_user_reviews_and_return for super::RemoteProcedures {
fn list_admin_game_distribution_user_reviews_and_return_then(
&self,
input: GameDistributionAdminUserReviewListInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<GameDistributionAdminUserReviewResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, GameDistributionAdminUserReviewResult>(
"list_admin_game_distribution_user_reviews_and_return",
ListAdminGameDistributionUserReviewsAndReturnArgs { input },
__callback,
);
}
}

Some files were not shown because too many files have changed in this diff Show More