Files
Genarrative/server-rs/crates/spacetime-client/src/mapper/puzzle.rs

1085 lines
36 KiB
Rust

use super::*;
pub(crate) fn map_puzzle_agent_session_procedure_result(
result: PuzzleAgentSessionProcedureResult,
) -> Result<PuzzleAgentSessionRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
let session = result
.session
.ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle agent session 快照"))?;
Ok(map_puzzle_agent_session_snapshot(session))
}
pub(crate) fn map_puzzle_work_procedure_result(
result: PuzzleWorkProcedureResult,
) -> Result<PuzzleWorkProfileRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
let item = result
.item
.ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle work 快照"))?;
Ok(map_puzzle_work_profile(item))
}
pub(crate) fn map_puzzle_works_procedure_result(
result: PuzzleWorksProcedureResult,
) -> Result<Vec<PuzzleWorkProfileRecord>, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
Ok(result
.items
.into_iter()
.map(map_puzzle_work_profile)
.collect())
}
pub(crate) fn map_puzzle_run_procedure_result(
result: PuzzleRunProcedureResult,
) -> Result<PuzzleRunRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
let run = result
.run
.ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle run 快照"))?;
Ok(map_puzzle_run_snapshot(run))
}
pub(crate) fn map_puzzle_agent_session_snapshot(
snapshot: PuzzleAgentSessionSnapshot,
) -> PuzzleAgentSessionRecord {
PuzzleAgentSessionRecord {
session_id: snapshot.session_id,
seed_text: snapshot.seed_text,
current_turn: snapshot.current_turn,
progress_percent: snapshot.progress_percent,
stage: format_puzzle_agent_stage(snapshot.stage).to_string(),
anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack),
draft: snapshot.draft.map(map_puzzle_result_draft),
messages: snapshot
.messages
.into_iter()
.map(map_puzzle_agent_message_snapshot)
.collect(),
last_assistant_reply: snapshot.last_assistant_reply,
published_profile_id: snapshot.published_profile_id,
suggested_actions: snapshot
.suggested_actions
.into_iter()
.map(map_puzzle_suggested_action)
.collect(),
result_preview: snapshot.result_preview.map(map_puzzle_result_preview),
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
}
}
pub(crate) fn map_puzzle_anchor_pack(snapshot: PuzzleAnchorPack) -> PuzzleAnchorPackRecord {
PuzzleAnchorPackRecord {
theme_promise: map_puzzle_anchor_item(snapshot.theme_promise),
visual_subject: map_puzzle_anchor_item(snapshot.visual_subject),
visual_mood: map_puzzle_anchor_item(snapshot.visual_mood),
composition_hooks: map_puzzle_anchor_item(snapshot.composition_hooks),
tags_and_forbidden: map_puzzle_anchor_item(snapshot.tags_and_forbidden),
}
}
pub(crate) fn map_puzzle_anchor_item(snapshot: PuzzleAnchorItem) -> PuzzleAnchorItemRecord {
PuzzleAnchorItemRecord {
key: snapshot.key,
label: snapshot.label,
value: snapshot.value,
status: format_puzzle_anchor_status(snapshot.status).to_string(),
}
}
pub(crate) fn map_puzzle_result_draft(snapshot: PuzzleResultDraft) -> PuzzleResultDraftRecord {
PuzzleResultDraftRecord {
work_title: snapshot.work_title,
work_description: snapshot.work_description,
level_name: snapshot.level_name,
summary: snapshot.summary,
theme_tags: snapshot.theme_tags,
forbidden_directives: snapshot.forbidden_directives,
creator_intent: snapshot.creator_intent.map(map_puzzle_creator_intent),
anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack),
candidates: snapshot
.candidates
.into_iter()
.map(map_puzzle_generated_image_candidate)
.collect(),
selected_candidate_id: snapshot.selected_candidate_id,
cover_image_src: snapshot.cover_image_src,
cover_asset_id: snapshot.cover_asset_id,
generation_status: snapshot.generation_status,
levels: snapshot
.levels
.into_iter()
.map(map_puzzle_draft_level)
.collect(),
form_draft: snapshot.form_draft.map(map_puzzle_form_draft),
}
}
pub(crate) fn map_puzzle_form_draft(snapshot: PuzzleFormDraft) -> PuzzleFormDraftRecord {
PuzzleFormDraftRecord {
work_title: snapshot.work_title,
work_description: snapshot.work_description,
picture_description: snapshot.picture_description,
}
}
pub(crate) fn map_puzzle_draft_level(snapshot: PuzzleDraftLevel) -> PuzzleDraftLevelRecord {
PuzzleDraftLevelRecord {
level_id: snapshot.level_id,
level_name: snapshot.level_name,
picture_description: snapshot.picture_description,
picture_reference: snapshot.picture_reference,
ui_background_prompt: snapshot.ui_background_prompt,
ui_background_image_src: snapshot.ui_background_image_src,
ui_background_image_object_key: snapshot.ui_background_image_object_key,
background_music: snapshot.background_music.map(map_puzzle_audio_asset),
candidates: snapshot
.candidates
.into_iter()
.map(map_puzzle_generated_image_candidate)
.collect(),
selected_candidate_id: snapshot.selected_candidate_id,
cover_image_src: snapshot.cover_image_src,
cover_asset_id: snapshot.cover_asset_id,
generation_status: snapshot.generation_status,
}
}
pub(crate) fn map_puzzle_audio_asset(asset: PuzzleAudioAsset) -> PuzzleAudioAssetRecord {
PuzzleAudioAssetRecord {
task_id: asset.task_id,
provider: asset.provider,
asset_object_id: asset.asset_object_id,
asset_kind: asset.asset_kind,
audio_src: asset.audio_src,
prompt: asset.prompt,
title: asset.title,
updated_at: asset.updated_at,
}
}
pub(crate) fn map_puzzle_creator_intent(
snapshot: PuzzleCreatorIntent,
) -> PuzzleCreatorIntentRecord {
PuzzleCreatorIntentRecord {
source_mode: snapshot.source_mode,
raw_messages_summary: snapshot.raw_messages_summary,
theme_promise: snapshot.theme_promise,
visual_subject: snapshot.visual_subject,
visual_mood: snapshot.visual_mood,
composition_hooks: snapshot.composition_hooks,
theme_tags: snapshot.theme_tags,
forbidden_directives: snapshot.forbidden_directives,
}
}
pub(crate) fn map_puzzle_generated_image_candidate(
snapshot: PuzzleGeneratedImageCandidate,
) -> PuzzleGeneratedImageCandidateRecord {
PuzzleGeneratedImageCandidateRecord {
candidate_id: snapshot.candidate_id,
image_src: snapshot.image_src,
asset_id: snapshot.asset_id,
prompt: snapshot.prompt,
actual_prompt: snapshot.actual_prompt,
source_type: snapshot.source_type,
selected: snapshot.selected,
}
}
pub(crate) fn map_puzzle_agent_message_snapshot(
snapshot: PuzzleAgentMessageSnapshot,
) -> PuzzleAgentMessageRecord {
PuzzleAgentMessageRecord {
message_id: snapshot.message_id,
role: format_puzzle_agent_message_role(snapshot.role).to_string(),
kind: format_puzzle_agent_message_kind(snapshot.kind).to_string(),
text: snapshot.text,
created_at: format_timestamp_micros(snapshot.created_at_micros),
}
}
pub(crate) fn map_puzzle_suggested_action(
snapshot: PuzzleAgentSuggestedAction,
) -> PuzzleAgentSuggestedActionRecord {
PuzzleAgentSuggestedActionRecord {
action_id: snapshot.id,
action_type: snapshot.action_type,
label: snapshot.label,
}
}
pub(crate) fn map_puzzle_result_preview(
snapshot: PuzzleResultPreviewEnvelope,
) -> PuzzleResultPreviewRecord {
PuzzleResultPreviewRecord {
draft: map_puzzle_result_draft(snapshot.draft),
blockers: snapshot
.blockers
.into_iter()
.map(map_puzzle_result_preview_blocker)
.collect(),
quality_findings: snapshot
.quality_findings
.into_iter()
.map(map_puzzle_result_preview_finding)
.collect(),
publish_ready: snapshot.publish_ready,
}
}
pub(crate) fn map_puzzle_result_preview_blocker(
snapshot: PuzzleResultPreviewBlocker,
) -> PuzzleResultPreviewBlockerRecord {
PuzzleResultPreviewBlockerRecord {
blocker_id: snapshot.id,
code: snapshot.code,
message: snapshot.message,
}
}
pub(crate) fn map_puzzle_result_preview_finding(
snapshot: PuzzleResultPreviewFinding,
) -> PuzzleResultPreviewFindingRecord {
PuzzleResultPreviewFindingRecord {
finding_id: snapshot.id,
severity: snapshot.severity,
code: snapshot.code,
message: snapshot.message,
}
}
pub(crate) fn map_puzzle_work_profile(snapshot: PuzzleWorkProfile) -> PuzzleWorkProfileRecord {
PuzzleWorkProfileRecord {
work_id: snapshot.work_id,
profile_id: snapshot.profile_id,
owner_user_id: snapshot.owner_user_id,
source_session_id: snapshot.source_session_id,
author_display_name: snapshot.author_display_name,
work_title: snapshot.work_title,
work_description: snapshot.work_description,
level_name: snapshot.level_name,
summary: snapshot.summary,
theme_tags: snapshot.theme_tags,
cover_image_src: snapshot.cover_image_src,
cover_asset_id: snapshot.cover_asset_id,
publication_status: format_puzzle_publication_status(snapshot.publication_status)
.to_string(),
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
play_count: snapshot.play_count,
remix_count: snapshot.remix_count,
like_count: snapshot.like_count,
recent_play_count_7d: snapshot.recent_play_count_7_d,
point_incentive_total_half_points: snapshot.point_incentive_total_half_points,
point_incentive_claimed_points: snapshot.point_incentive_claimed_points,
publish_ready: snapshot.publish_ready,
anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack),
levels: snapshot
.levels
.into_iter()
.map(map_puzzle_draft_level)
.collect(),
}
}
pub(crate) fn map_puzzle_gallery_card_view_row(
snapshot: PuzzleGalleryCardViewRow,
recent_play_count_7d: u32,
) -> PuzzleGalleryCardRecord {
PuzzleGalleryCardRecord {
work_id: snapshot.work_id,
profile_id: snapshot.profile_id,
owner_user_id: snapshot.owner_user_id,
source_session_id: snapshot.source_session_id,
author_display_name: snapshot.author_display_name,
work_title: snapshot.work_title,
work_description: snapshot.work_description,
level_name: snapshot.level_name,
summary: snapshot.summary,
theme_tags: snapshot.theme_tags,
cover_image_src: snapshot.cover_image_src,
cover_asset_id: snapshot.cover_asset_id,
publication_status: format_puzzle_publication_status(snapshot.publication_status)
.to_string(),
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
play_count: snapshot.play_count,
remix_count: snapshot.remix_count,
like_count: snapshot.like_count,
recent_play_count_7d,
point_incentive_total_half_points: snapshot.point_incentive_total_half_points,
point_incentive_claimed_points: snapshot.point_incentive_claimed_points,
publish_ready: snapshot.publish_ready,
generation_status: snapshot.generation_status,
}
}
pub(crate) fn map_puzzle_run_snapshot(snapshot: PuzzleRunSnapshot) -> PuzzleRunRecord {
PuzzleRunRecord {
run_id: snapshot.run_id,
entry_profile_id: snapshot.entry_profile_id,
cleared_level_count: snapshot.cleared_level_count,
current_level_index: snapshot.current_level_index,
current_grid_size: snapshot.current_grid_size,
played_profile_ids: snapshot.played_profile_ids,
previous_level_tags: snapshot.previous_level_tags,
current_level: snapshot
.current_level
.map(map_puzzle_runtime_level_snapshot),
recommended_next_profile_id: snapshot.recommended_next_profile_id,
next_level_mode: snapshot.next_level_mode,
next_level_profile_id: snapshot.next_level_profile_id,
next_level_id: snapshot.next_level_id,
recommended_next_works: snapshot
.recommended_next_works
.into_iter()
.map(map_puzzle_recommended_next_work)
.collect(),
leaderboard_entries: snapshot
.leaderboard_entries
.into_iter()
.map(map_puzzle_leaderboard_entry)
.collect(),
}
}
fn map_puzzle_recommended_next_work(
snapshot: PuzzleRecommendedNextWork,
) -> PuzzleRecommendedNextWorkRecord {
PuzzleRecommendedNextWorkRecord {
profile_id: snapshot.profile_id,
level_name: snapshot.level_name,
author_display_name: snapshot.author_display_name,
theme_tags: snapshot.theme_tags,
cover_image_src: snapshot.cover_image_src,
similarity_score: snapshot.similarity_score,
}
}
pub(crate) fn map_puzzle_runtime_level_snapshot(
snapshot: PuzzleRuntimeLevelSnapshot,
) -> PuzzleRuntimeLevelRecord {
let started_at_ms = if snapshot.started_at_ms == 0 {
// 中文注释:运行态快照缺少可用开始时间时只补一个可用值,其余限时字段保持快照原值。
current_unix_millis_for_legacy_puzzle_snapshot()
} else {
snapshot.started_at_ms
};
PuzzleRuntimeLevelRecord {
run_id: snapshot.run_id,
level_index: snapshot.level_index,
level_id: snapshot.level_id,
grid_size: snapshot.grid_size,
profile_id: snapshot.profile_id,
level_name: snapshot.level_name,
author_display_name: snapshot.author_display_name,
theme_tags: snapshot.theme_tags,
cover_image_src: snapshot.cover_image_src,
ui_background_image_src: snapshot.ui_background_image_src,
ui_background_image_object_key: snapshot.ui_background_image_object_key,
background_music: snapshot.background_music.map(map_puzzle_audio_asset),
board: map_puzzle_board_snapshot(snapshot.board),
status: format_puzzle_runtime_level_status(snapshot.status).to_string(),
started_at_ms,
cleared_at_ms: snapshot.cleared_at_ms,
elapsed_ms: snapshot.elapsed_ms,
time_limit_ms: snapshot.time_limit_ms,
remaining_ms: snapshot.remaining_ms,
paused_accumulated_ms: snapshot.paused_accumulated_ms,
pause_started_at_ms: snapshot.pause_started_at_ms,
freeze_accumulated_ms: snapshot.freeze_accumulated_ms,
freeze_started_at_ms: snapshot.freeze_started_at_ms,
freeze_until_ms: snapshot.freeze_until_ms,
leaderboard_entries: snapshot
.leaderboard_entries
.into_iter()
.map(map_puzzle_leaderboard_entry)
.collect(),
}
}
fn current_unix_millis_for_legacy_puzzle_snapshot() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|duration| duration.as_millis().min(u128::from(u64::MAX)) as u64)
.unwrap_or(1)
}
pub(crate) fn map_puzzle_leaderboard_entry(
snapshot: PuzzleLeaderboardEntry,
) -> PuzzleLeaderboardEntryRecord {
PuzzleLeaderboardEntryRecord {
rank: snapshot.rank,
nickname: snapshot.nickname,
elapsed_ms: snapshot.elapsed_ms,
visible_tags: snapshot.visible_tags,
is_current_player: snapshot.is_current_player,
}
}
pub(crate) fn map_puzzle_board_snapshot(snapshot: PuzzleBoardSnapshot) -> PuzzleBoardRecord {
PuzzleBoardRecord {
rows: snapshot.rows,
cols: snapshot.cols,
pieces: snapshot
.pieces
.into_iter()
.map(map_puzzle_piece_state)
.collect(),
merged_groups: snapshot
.merged_groups
.into_iter()
.map(map_puzzle_merged_group_state)
.collect(),
selected_piece_id: snapshot.selected_piece_id,
all_tiles_resolved: snapshot.all_tiles_resolved,
}
}
pub(crate) fn map_puzzle_piece_state(snapshot: PuzzlePieceState) -> PuzzlePieceStateRecord {
PuzzlePieceStateRecord {
piece_id: snapshot.piece_id,
correct_row: snapshot.correct_row,
correct_col: snapshot.correct_col,
current_row: snapshot.current_row,
current_col: snapshot.current_col,
merged_group_id: snapshot.merged_group_id,
}
}
pub(crate) fn map_puzzle_merged_group_state(
snapshot: PuzzleMergedGroupState,
) -> PuzzleMergedGroupRecord {
PuzzleMergedGroupRecord {
group_id: snapshot.group_id,
piece_ids: snapshot.piece_ids,
occupied_cells: snapshot
.occupied_cells
.into_iter()
.map(map_puzzle_cell_position)
.collect(),
}
}
pub(crate) fn map_puzzle_cell_position(snapshot: PuzzleCellPosition) -> PuzzleCellPositionRecord {
PuzzleCellPositionRecord {
row: snapshot.row,
col: snapshot.col,
}
}
pub(crate) fn parse_puzzle_agent_stage_record(
value: &str,
) -> Result<crate::module_bindings::PuzzleAgentStage, SpacetimeClientError> {
match value.trim() {
"collecting_anchors" => Ok(crate::module_bindings::PuzzleAgentStage::CollectingAnchors),
"draft_ready" => Ok(crate::module_bindings::PuzzleAgentStage::DraftReady),
"image_refining" => Ok(crate::module_bindings::PuzzleAgentStage::ImageRefining),
"ready_to_publish" => Ok(crate::module_bindings::PuzzleAgentStage::ReadyToPublish),
"published" => Ok(crate::module_bindings::PuzzleAgentStage::Published),
other => Err(SpacetimeClientError::Runtime(format!(
"未知 puzzle agent stage: {other}"
))),
}
}
pub(crate) fn format_puzzle_agent_stage(value: PuzzleAgentStage) -> &'static str {
match value {
PuzzleAgentStage::CollectingAnchors => "collecting_anchors",
PuzzleAgentStage::DraftReady => "draft_ready",
PuzzleAgentStage::ImageRefining => "image_refining",
PuzzleAgentStage::ReadyToPublish => "ready_to_publish",
PuzzleAgentStage::Published => "published",
}
}
pub(crate) fn format_puzzle_anchor_status(value: PuzzleAnchorStatus) -> &'static str {
match value {
PuzzleAnchorStatus::Missing => "missing",
PuzzleAnchorStatus::Inferred => "inferred",
PuzzleAnchorStatus::Confirmed => "confirmed",
PuzzleAnchorStatus::Locked => "locked",
}
}
pub(crate) fn format_puzzle_agent_message_role(value: PuzzleAgentMessageRole) -> &'static str {
match value {
PuzzleAgentMessageRole::User => "user",
PuzzleAgentMessageRole::Assistant => "assistant",
PuzzleAgentMessageRole::System => "system",
}
}
pub(crate) fn format_puzzle_agent_message_kind(value: PuzzleAgentMessageKind) -> &'static str {
match value {
PuzzleAgentMessageKind::Chat => "chat",
PuzzleAgentMessageKind::Summary => "summary",
PuzzleAgentMessageKind::ActionResult => "action_result",
PuzzleAgentMessageKind::Warning => "warning",
}
}
pub(crate) fn format_puzzle_publication_status(value: PuzzlePublicationStatus) -> &'static str {
match value {
PuzzlePublicationStatus::Draft => "draft",
PuzzlePublicationStatus::Published => "published",
}
}
pub(crate) fn format_puzzle_runtime_level_status(value: PuzzleRuntimeLevelStatus) -> &'static str {
match value {
PuzzleRuntimeLevelStatus::Playing => "playing",
PuzzleRuntimeLevelStatus::Cleared => "cleared",
PuzzleRuntimeLevelStatus::Failed => "failed",
}
}
pub(crate) fn map_runtime_profile_wallet_ledger_source_type_back(
value: crate::module_bindings::RuntimeProfileWalletLedgerSourceType,
) -> module_runtime::RuntimeProfileWalletLedgerSourceType {
match value {
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::SnapshotSync => {
module_runtime::RuntimeProfileWalletLedgerSourceType::SnapshotSync
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::NewUserRegistrationReward => {
module_runtime::RuntimeProfileWalletLedgerSourceType::NewUserRegistrationReward
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::InviteInviterReward => {
module_runtime::RuntimeProfileWalletLedgerSourceType::InviteInviterReward
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::InviteInviteeReward => {
module_runtime::RuntimeProfileWalletLedgerSourceType::InviteInviteeReward
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::PointsRecharge => {
module_runtime::RuntimeProfileWalletLedgerSourceType::PointsRecharge
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::AssetOperationConsume => {
module_runtime::RuntimeProfileWalletLedgerSourceType::AssetOperationConsume
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::AssetOperationRefund => {
module_runtime::RuntimeProfileWalletLedgerSourceType::AssetOperationRefund
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::RedeemCodeReward => {
module_runtime::RuntimeProfileWalletLedgerSourceType::RedeemCodeReward
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim => {
module_runtime::RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim
}
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::DailyTaskReward => {
module_runtime::RuntimeProfileWalletLedgerSourceType::DailyTaskReward
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAgentSessionCreateRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub seed_text: String,
pub welcome_message_id: String,
pub welcome_message_text: String,
pub created_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleFormDraftSaveRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub seed_text: String,
pub saved_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAgentMessageSubmitRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub user_message_id: String,
pub user_message_text: String,
pub submitted_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAgentMessageFinalizeRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub assistant_message_id: Option<String>,
pub assistant_reply_text: Option<String>,
pub stage: String,
pub progress_percent: u32,
pub anchor_pack_json: String,
pub error_message: Option<String>,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleGeneratedImagesSaveRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub level_id: Option<String>,
pub levels_json: Option<String>,
pub candidates_json: String,
pub saved_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleUiBackgroundSaveRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub level_id: Option<String>,
pub levels_json: Option<String>,
pub prompt: String,
pub image_src: String,
pub image_object_key: Option<String>,
pub saved_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleSelectCoverImageRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub level_id: Option<String>,
pub candidate_id: String,
pub selected_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzlePublishRecordInput {
pub session_id: String,
pub owner_user_id: String,
pub work_id: String,
pub profile_id: String,
pub author_display_name: String,
pub work_title: Option<String>,
pub work_description: Option<String>,
pub level_name: Option<String>,
pub summary: Option<String>,
pub theme_tags: Option<Vec<String>>,
pub levels_json: Option<String>,
pub published_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleWorkUpsertRecordInput {
pub profile_id: String,
pub owner_user_id: String,
pub work_title: String,
pub work_description: String,
pub level_name: String,
pub summary: String,
pub theme_tags: Vec<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub levels_json: Option<String>,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleWorkRemixRecordInput {
pub source_profile_id: String,
pub target_owner_user_id: String,
pub target_session_id: String,
pub target_profile_id: String,
pub target_work_id: String,
pub author_display_name: String,
pub welcome_message_id: String,
pub remixed_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleWorkLikeReportRecordInput {
pub profile_id: String,
pub user_id: String,
pub liked_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRunStartRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub profile_id: String,
pub level_id: Option<String>,
pub started_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRunSwapRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub first_piece_id: String,
pub second_piece_id: String,
pub swapped_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRunDragRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub piece_id: String,
pub target_row: u32,
pub target_col: u32,
pub dragged_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRunNextLevelRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub target_profile_id: Option<String>,
pub advanced_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRunPauseRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub paused: bool,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRunPropRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub prop_kind: String,
pub used_at_micros: i64,
pub spent_points: u64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAnchorItemRecord {
pub key: String,
pub label: String,
pub value: String,
pub status: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAnchorPackRecord {
pub theme_promise: PuzzleAnchorItemRecord,
pub visual_subject: PuzzleAnchorItemRecord,
pub visual_mood: PuzzleAnchorItemRecord,
pub composition_hooks: PuzzleAnchorItemRecord,
pub tags_and_forbidden: PuzzleAnchorItemRecord,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleCreatorIntentRecord {
pub source_mode: String,
pub raw_messages_summary: String,
pub theme_promise: String,
pub visual_subject: String,
pub visual_mood: Vec<String>,
pub composition_hooks: Vec<String>,
pub theme_tags: Vec<String>,
pub forbidden_directives: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleGeneratedImageCandidateRecord {
pub candidate_id: String,
pub image_src: String,
pub asset_id: String,
pub prompt: String,
pub actual_prompt: Option<String>,
pub source_type: String,
pub selected: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleResultDraftRecord {
pub work_title: String,
pub work_description: String,
pub level_name: String,
pub summary: String,
pub theme_tags: Vec<String>,
pub forbidden_directives: Vec<String>,
pub creator_intent: Option<PuzzleCreatorIntentRecord>,
pub anchor_pack: PuzzleAnchorPackRecord,
pub candidates: Vec<PuzzleGeneratedImageCandidateRecord>,
pub selected_candidate_id: Option<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub generation_status: String,
pub levels: Vec<PuzzleDraftLevelRecord>,
pub form_draft: Option<PuzzleFormDraftRecord>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleFormDraftRecord {
pub work_title: Option<String>,
pub work_description: Option<String>,
pub picture_description: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleDraftLevelRecord {
pub level_id: String,
pub level_name: String,
pub picture_description: String,
pub picture_reference: Option<String>,
pub ui_background_prompt: Option<String>,
pub ui_background_image_src: Option<String>,
pub ui_background_image_object_key: Option<String>,
pub background_music: Option<PuzzleAudioAssetRecord>,
pub candidates: Vec<PuzzleGeneratedImageCandidateRecord>,
pub selected_candidate_id: Option<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub generation_status: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAudioAssetRecord {
pub task_id: String,
pub provider: String,
pub asset_object_id: Option<String>,
pub asset_kind: Option<String>,
pub audio_src: String,
pub prompt: Option<String>,
pub title: Option<String>,
pub updated_at: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAgentMessageRecord {
pub message_id: String,
pub role: String,
pub kind: String,
pub text: String,
pub created_at: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAgentSuggestedActionRecord {
pub action_id: String,
pub action_type: String,
pub label: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleResultPreviewBlockerRecord {
pub blocker_id: String,
pub code: String,
pub message: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleResultPreviewFindingRecord {
pub finding_id: String,
pub severity: String,
pub code: String,
pub message: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleResultPreviewRecord {
pub draft: PuzzleResultDraftRecord,
pub blockers: Vec<PuzzleResultPreviewBlockerRecord>,
pub quality_findings: Vec<PuzzleResultPreviewFindingRecord>,
pub publish_ready: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleAgentSessionRecord {
pub session_id: String,
pub seed_text: String,
pub current_turn: u32,
pub progress_percent: u32,
pub stage: String,
pub anchor_pack: PuzzleAnchorPackRecord,
pub draft: Option<PuzzleResultDraftRecord>,
pub messages: Vec<PuzzleAgentMessageRecord>,
pub last_assistant_reply: Option<String>,
pub published_profile_id: Option<String>,
pub suggested_actions: Vec<PuzzleAgentSuggestedActionRecord>,
pub result_preview: Option<PuzzleResultPreviewRecord>,
pub updated_at: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleWorkProfileRecord {
pub work_id: String,
pub profile_id: String,
pub owner_user_id: String,
pub source_session_id: Option<String>,
pub author_display_name: String,
pub work_title: String,
pub work_description: String,
pub level_name: String,
pub summary: String,
pub theme_tags: Vec<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub publication_status: String,
pub updated_at: String,
pub published_at: Option<String>,
pub play_count: u32,
pub remix_count: u32,
pub like_count: u32,
pub recent_play_count_7d: u32,
pub point_incentive_total_half_points: u64,
pub point_incentive_claimed_points: u64,
pub publish_ready: bool,
pub anchor_pack: PuzzleAnchorPackRecord,
pub levels: Vec<PuzzleDraftLevelRecord>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleGalleryCardRecord {
pub work_id: String,
pub profile_id: String,
pub owner_user_id: String,
pub source_session_id: Option<String>,
pub author_display_name: String,
pub work_title: String,
pub work_description: String,
pub level_name: String,
pub summary: String,
pub theme_tags: Vec<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub publication_status: String,
pub updated_at: String,
pub published_at: Option<String>,
pub play_count: u32,
pub remix_count: u32,
pub like_count: u32,
pub recent_play_count_7d: u32,
pub point_incentive_total_half_points: u64,
pub point_incentive_claimed_points: u64,
pub publish_ready: bool,
pub generation_status: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleWorkPointIncentiveClaimRecordInput {
pub profile_id: String,
pub owner_user_id: String,
pub claimed_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleCellPositionRecord {
pub row: u32,
pub col: u32,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzlePieceStateRecord {
pub piece_id: String,
pub correct_row: u32,
pub correct_col: u32,
pub current_row: u32,
pub current_col: u32,
pub merged_group_id: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleMergedGroupRecord {
pub group_id: String,
pub piece_ids: Vec<String>,
pub occupied_cells: Vec<PuzzleCellPositionRecord>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleLeaderboardEntryRecord {
pub rank: u32,
pub nickname: String,
pub elapsed_ms: u64,
pub visible_tags: Vec<String>,
pub is_current_player: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleBoardRecord {
pub rows: u32,
pub cols: u32,
pub pieces: Vec<PuzzlePieceStateRecord>,
pub merged_groups: Vec<PuzzleMergedGroupRecord>,
pub selected_piece_id: Option<String>,
pub all_tiles_resolved: bool,
}
#[derive(Clone, Debug, PartialEq)]
pub struct PuzzleRecommendedNextWorkRecord {
pub profile_id: String,
pub level_name: String,
pub author_display_name: String,
pub theme_tags: Vec<String>,
pub cover_image_src: Option<String>,
pub similarity_score: f32,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleRuntimeLevelRecord {
pub run_id: String,
pub level_index: u32,
pub level_id: Option<String>,
pub grid_size: u32,
pub profile_id: String,
pub level_name: String,
pub author_display_name: String,
pub theme_tags: Vec<String>,
pub cover_image_src: Option<String>,
pub ui_background_image_src: Option<String>,
pub ui_background_image_object_key: Option<String>,
pub background_music: Option<PuzzleAudioAssetRecord>,
pub board: PuzzleBoardRecord,
pub status: String,
pub started_at_ms: u64,
pub cleared_at_ms: Option<u64>,
pub elapsed_ms: Option<u64>,
pub time_limit_ms: u64,
pub remaining_ms: u64,
pub paused_accumulated_ms: u64,
pub pause_started_at_ms: Option<u64>,
pub freeze_accumulated_ms: u64,
pub freeze_started_at_ms: Option<u64>,
pub freeze_until_ms: Option<u64>,
pub leaderboard_entries: Vec<PuzzleLeaderboardEntryRecord>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct PuzzleRunRecord {
pub run_id: String,
pub entry_profile_id: String,
pub cleared_level_count: u32,
pub current_level_index: u32,
pub current_grid_size: u32,
pub played_profile_ids: Vec<String>,
pub previous_level_tags: Vec<String>,
pub current_level: Option<PuzzleRuntimeLevelRecord>,
pub recommended_next_profile_id: Option<String>,
pub next_level_mode: String,
pub next_level_profile_id: Option<String>,
pub next_level_id: Option<String>,
pub recommended_next_works: Vec<PuzzleRecommendedNextWorkRecord>,
pub leaderboard_entries: Vec<PuzzleLeaderboardEntryRecord>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PuzzleLeaderboardSubmitRecordInput {
pub run_id: String,
pub owner_user_id: String,
pub profile_id: String,
pub grid_size: u32,
pub elapsed_ms: u64,
pub nickname: String,
pub submitted_at_micros: i64,
}