fix: tighten public work type routing
This commit is contained in:
@@ -1662,9 +1662,7 @@ fn get_custom_world_gallery_detail_record(
|
||||
.find(&input.profile_id)
|
||||
.filter(|row| {
|
||||
row.owner_user_id == input.owner_user_id
|
||||
&& row.publication_status == CustomWorldPublicationStatus::Published
|
||||
&& row.deleted_at.is_none()
|
||||
&& row.visible
|
||||
&& is_custom_world_profile_publicly_interactive(row)
|
||||
});
|
||||
|
||||
let gallery_entry = ctx
|
||||
@@ -1712,8 +1710,7 @@ fn get_custom_world_gallery_detail_record_by_code(
|
||||
.find(&row.profile_id)
|
||||
.filter(|profile_row| {
|
||||
profile_row.owner_user_id == row.owner_user_id
|
||||
&& profile_row.publication_status == CustomWorldPublicationStatus::Published
|
||||
&& profile_row.deleted_at.is_none()
|
||||
&& is_custom_world_profile_publicly_interactive(profile_row)
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1756,12 +1753,7 @@ fn remix_custom_world_profile_record(
|
||||
.profile_id()
|
||||
.find(&source_profile_id.to_string())
|
||||
.filter(|row| row.owner_user_id == source_owner_user_id)
|
||||
.filter(|row| {
|
||||
row.publication_status == CustomWorldPublicationStatus::Published
|
||||
&& row.deleted_at.is_none()
|
||||
&& row.visible
|
||||
&& row.published_at.is_some()
|
||||
})
|
||||
.filter(is_custom_world_profile_publicly_interactive)
|
||||
.ok_or_else(|| "custom_world 已发布源作品不存在,无法改编".to_string())?;
|
||||
let remixed_at = Timestamp::from_micros_since_unix_epoch(input.remixed_at_micros);
|
||||
|
||||
@@ -1859,12 +1851,7 @@ fn record_custom_world_profile_play_record(
|
||||
.profile_id()
|
||||
.find(&profile_id.to_string())
|
||||
.filter(|row| row.owner_user_id == owner_user_id)
|
||||
.filter(|row| {
|
||||
row.publication_status == CustomWorldPublicationStatus::Published
|
||||
&& row.deleted_at.is_none()
|
||||
&& row.visible
|
||||
&& row.published_at.is_some()
|
||||
})
|
||||
.filter(is_custom_world_profile_publicly_interactive)
|
||||
.ok_or_else(|| "custom_world 已发布作品不存在,无法记录游玩".to_string())?;
|
||||
let played_at = Timestamp::from_micros_since_unix_epoch(input.played_at_micros);
|
||||
|
||||
@@ -1932,12 +1919,7 @@ fn record_custom_world_profile_like_record(
|
||||
.profile_id()
|
||||
.find(&profile_id.to_string())
|
||||
.filter(|row| row.owner_user_id == owner_user_id)
|
||||
.filter(|row| {
|
||||
row.publication_status == CustomWorldPublicationStatus::Published
|
||||
&& row.deleted_at.is_none()
|
||||
&& row.visible
|
||||
&& row.published_at.is_some()
|
||||
})
|
||||
.filter(is_custom_world_profile_publicly_interactive)
|
||||
.ok_or_else(|| "custom_world 已发布作品不存在,无法点赞".to_string())?;
|
||||
let liked_at = Timestamp::from_micros_since_unix_epoch(input.liked_at_micros);
|
||||
|
||||
@@ -1998,6 +1980,18 @@ fn record_custom_world_profile_like_record(
|
||||
))
|
||||
}
|
||||
|
||||
fn is_custom_world_profile_publicly_interactive(row: &CustomWorldProfile) -> bool {
|
||||
// 历史公开作品可能缺少 published_at;公开互动只按发布、未删除、可见判断。
|
||||
row.publication_status == CustomWorldPublicationStatus::Published
|
||||
&& row.deleted_at.is_none()
|
||||
&& row.visible
|
||||
}
|
||||
|
||||
fn resolve_custom_world_published_at(row: &CustomWorldProfile) -> Timestamp {
|
||||
// gallery 展示与同步兼容旧数据,用 updated_at 兜底公开时间。
|
||||
row.published_at.unwrap_or(row.updated_at)
|
||||
}
|
||||
|
||||
fn list_custom_world_work_snapshots(
|
||||
ctx: &ReducerContext,
|
||||
input: CustomWorldWorksListInput,
|
||||
@@ -4832,9 +4826,10 @@ fn sync_custom_world_gallery_entry_from_profile(
|
||||
ctx: &ReducerContext,
|
||||
profile: &CustomWorldProfile,
|
||||
) -> Result<CustomWorldGalleryEntrySnapshot, String> {
|
||||
let published_at = profile
|
||||
.published_at
|
||||
.ok_or_else(|| "published profile 缺少 published_at,无法同步 gallery".to_string())?;
|
||||
if profile.publication_status != CustomWorldPublicationStatus::Published {
|
||||
return Err("custom_world profile 未发布,无法同步 gallery".to_string());
|
||||
}
|
||||
let published_at = resolve_custom_world_published_at(profile);
|
||||
|
||||
ctx.db
|
||||
.custom_world_gallery_entry()
|
||||
@@ -4881,10 +4876,6 @@ fn sync_missing_custom_world_gallery_entries(ctx: &ReducerContext) -> Result<(),
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for profile in published_profiles {
|
||||
if profile.published_at.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let existing_gallery_entry = ctx
|
||||
.db
|
||||
.custom_world_gallery_entry()
|
||||
@@ -5483,6 +5474,78 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_world_public_interactions_accept_legacy_missing_published_at() {
|
||||
fn build_profile(
|
||||
publication_status: CustomWorldPublicationStatus,
|
||||
published_at: Option<Timestamp>,
|
||||
deleted_at: Option<Timestamp>,
|
||||
visible: bool,
|
||||
) -> CustomWorldProfile {
|
||||
CustomWorldProfile {
|
||||
profile_id: "profile-legacy".to_string(),
|
||||
owner_user_id: "user-legacy".to_string(),
|
||||
public_work_code: Some("CW-3A9EC89B".to_string()),
|
||||
author_public_user_code: Some("SY-00000001".to_string()),
|
||||
source_agent_session_id: Some("session-legacy".to_string()),
|
||||
publication_status,
|
||||
world_name: "旧公开世界".to_string(),
|
||||
subtitle: String::new(),
|
||||
summary_text: String::new(),
|
||||
theme_mode: CustomWorldThemeMode::Mythic,
|
||||
cover_image_src: None,
|
||||
profile_payload_json: "{}".to_string(),
|
||||
playable_npc_count: 0,
|
||||
landmark_count: 0,
|
||||
play_count: 0,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
author_display_name: "玩家".to_string(),
|
||||
published_at,
|
||||
deleted_at,
|
||||
created_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||
updated_at: Timestamp::from_micros_since_unix_epoch(20),
|
||||
visible,
|
||||
}
|
||||
}
|
||||
|
||||
let legacy_published =
|
||||
build_profile(CustomWorldPublicationStatus::Published, None, None, true);
|
||||
assert!(is_custom_world_profile_publicly_interactive(
|
||||
&legacy_published
|
||||
));
|
||||
assert_eq!(
|
||||
resolve_custom_world_published_at(&legacy_published).to_micros_since_unix_epoch(),
|
||||
20
|
||||
);
|
||||
|
||||
let current_published = build_profile(
|
||||
CustomWorldPublicationStatus::Published,
|
||||
Some(Timestamp::from_micros_since_unix_epoch(10)),
|
||||
None,
|
||||
true,
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_custom_world_published_at(¤t_published).to_micros_since_unix_epoch(),
|
||||
10
|
||||
);
|
||||
|
||||
assert!(!is_custom_world_profile_publicly_interactive(
|
||||
&build_profile(CustomWorldPublicationStatus::Draft, None, None, true,)
|
||||
));
|
||||
assert!(!is_custom_world_profile_publicly_interactive(
|
||||
&build_profile(
|
||||
CustomWorldPublicationStatus::Published,
|
||||
None,
|
||||
Some(Timestamp::from_micros_since_unix_epoch(30)),
|
||||
true,
|
||||
)
|
||||
));
|
||||
assert!(!is_custom_world_profile_publicly_interactive(
|
||||
&build_profile(CustomWorldPublicationStatus::Published, None, None, false,)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_world_works_hides_compiled_draft_profile_when_agent_session_is_active() {
|
||||
fn build_test_custom_world_profile(
|
||||
|
||||
@@ -1573,11 +1573,6 @@ mod tests {
|
||||
5, 1_000, &existing
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn jump_hop_delete_input_carries_owner_and_profile() {
|
||||
|
||||
Reference in New Issue
Block a user