From a6c8ad0cb643e7dcc335338e80809603d5c97df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 1 Sep 2026 18:05:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=94=99=E8=AF=AF=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E5=85=83=E6=95=B0=E6=8D=AE=E8=A1=A8=E4=B8=8E=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E9=97=A8=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 SpacetimeDB error_report 表及 CRUD procedure 生成并接入 spacetime-client 错误报告 facade 与 mapper --- .../crates/spacetime-client/src/active.rs | 2 + .../spacetime-client/src/active/mapper.rs | 7 + .../spacetime-client/src/error_reports.rs | 89 +++++ .../src/mapper/error_reports.rs | 125 ++++++ .../spacetime-client/src/module_bindings.rs | 61 ++- ...reate_error_report_and_return_procedure.rs | 59 +++ ...elete_error_report_and_return_procedure.rs | 59 +++ .../error_report_create_input_type.rs | 26 ++ .../error_report_delete_input_type.rs | 15 + .../error_report_get_input_type.rs | 15 + .../error_report_list_input_type.rs | 19 + .../error_report_procedure_result_type.rs | 21 ++ .../error_report_snapshot_type.rs | 29 ++ .../src/module_bindings/error_report_table.rs | 259 +++++++++++++ .../src/module_bindings/error_report_type.rs | 97 +++++ .../error_report_update_input_type.rs | 18 + .../get_error_report_and_return_procedure.rs | 59 +++ ...list_error_reports_and_return_procedure.rs | 59 +++ ...pdate_error_report_and_return_procedure.rs | 59 +++ .../crates/spacetime-module/src/active.rs | 3 + .../spacetime-module/src/error_report.rs | 357 ++++++++++++++++++ .../crates/spacetime-module/src/migration.rs | 1 + 22 files changed, 1433 insertions(+), 6 deletions(-) create mode 100644 server-rs/crates/spacetime-client/src/error_reports.rs create mode 100644 server-rs/crates/spacetime-client/src/mapper/error_reports.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/create_error_report_and_return_procedure.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/delete_error_report_and_return_procedure.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_create_input_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_delete_input_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_get_input_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_list_input_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_procedure_result_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_snapshot_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_table.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/error_report_update_input_type.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/get_error_report_and_return_procedure.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/list_error_reports_and_return_procedure.rs create mode 100644 server-rs/crates/spacetime-client/src/module_bindings/update_error_report_and_return_procedure.rs create mode 100644 server-rs/crates/spacetime-module/src/error_report.rs diff --git a/server-rs/crates/spacetime-client/src/active.rs b/server-rs/crates/spacetime-client/src/active.rs index dc9096de5..8eac28ff2 100644 --- a/server-rs/crates/spacetime-client/src/active.rs +++ b/server-rs/crates/spacetime-client/src/active.rs @@ -15,6 +15,8 @@ pub mod assets; pub mod auth; pub mod editor_agent; pub mod editor_project; +#[path = "error_reports.rs"] +mod error_reports; pub mod external_api_key; #[path = "active/external_generation.rs"] pub mod external_generation; diff --git a/server-rs/crates/spacetime-client/src/active/mapper.rs b/server-rs/crates/spacetime-client/src/active/mapper.rs index 66845286e..f4fb8e017 100644 --- a/server-rs/crates/spacetime-client/src/active/mapper.rs +++ b/server-rs/crates/spacetime-client/src/active/mapper.rs @@ -14,6 +14,8 @@ mod auth; mod editor_agent; #[path = "mapper/editor_project.rs"] mod editor_project; +#[path = "../mapper/error_reports.rs"] +mod error_reports; #[path = "mapper/external_api_key.rs"] mod external_api_key; #[path = "mapper/external_generation.rs"] @@ -67,6 +69,10 @@ pub use self::editor_project::{ EditorShowcaseAssetViewerRecord, EditorShowcaseCampaignConfigGetRecordInput, EditorShowcaseCampaignConfigRecord, EditorShowcaseCampaignConfigUpsertRecordInput, }; +pub use self::error_reports::{ + ErrorReportCreateRecordInput, ErrorReportListRecordInput, ErrorReportRecord, + ErrorReportUpdateRecordInput, +}; pub use self::external_api_key::{ ExternalApiKeyAuthenticateRecordInput, ExternalApiKeyCreateRecordInput, ExternalApiKeyRecord, ExternalApiKeyRevokeRecordInput, @@ -118,6 +124,7 @@ pub(crate) use self::editor_project::{ map_editor_showcase_campaign_config_procedure_result, map_optional_editor_asset_procedure_result, }; +pub(crate) use self::error_reports::{map_error_report_list_result, map_error_report_result}; pub(crate) use self::external_api_key::{ map_external_api_key_list_procedure_result, map_external_api_key_single_procedure_result, }; diff --git a/server-rs/crates/spacetime-client/src/error_reports.rs b/server-rs/crates/spacetime-client/src/error_reports.rs new file mode 100644 index 000000000..dc0928264 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/error_reports.rs @@ -0,0 +1,89 @@ +use super::*; + +impl SpacetimeClient { + pub async fn create_error_report( + &self, + input: ErrorReportCreateRecordInput, + ) -> Result { + let input = input.into(); + self.call_after_connect("create_error_report_and_return", move |c, s| { + c.procedures() + .create_error_report_and_return_then(input, move |_, r| { + send_once( + &s, + r.map_err(SpacetimeClientError::from_sdk_error) + .and_then(map_error_report_result), + ) + }) + }) + .await + } + pub async fn get_error_report( + &self, + batch_id: String, + ) -> Result { + let input = ErrorReportGetInput { batch_id }; + self.call_after_connect("get_error_report_and_return", move |c, s| { + c.procedures() + .get_error_report_and_return_then(input, move |_, r| { + send_once( + &s, + r.map_err(SpacetimeClientError::from_sdk_error) + .and_then(map_error_report_result), + ) + }) + }) + .await + } + pub async fn list_error_reports( + &self, + input: ErrorReportListRecordInput, + ) -> Result<(Vec, u64), SpacetimeClientError> { + let input = input.into(); + self.call_after_connect("list_error_reports_and_return", move |c, s| { + c.procedures() + .list_error_reports_and_return_then(input, move |_, r| { + send_once( + &s, + r.map_err(SpacetimeClientError::from_sdk_error) + .and_then(map_error_report_list_result), + ) + }) + }) + .await + } + pub async fn update_error_report( + &self, + input: ErrorReportUpdateRecordInput, + ) -> Result { + let input = input.into(); + self.call_after_connect("update_error_report_and_return", move |c, s| { + c.procedures() + .update_error_report_and_return_then(input, move |_, r| { + send_once( + &s, + r.map_err(SpacetimeClientError::from_sdk_error) + .and_then(map_error_report_result), + ) + }) + }) + .await + } + pub async fn delete_error_report( + &self, + batch_id: String, + ) -> Result { + let input = ErrorReportDeleteInput { batch_id }; + self.call_after_connect("delete_error_report_and_return", move |c, s| { + c.procedures() + .delete_error_report_and_return_then(input, move |_, r| { + send_once( + &s, + r.map_err(SpacetimeClientError::from_sdk_error) + .and_then(map_error_report_result), + ) + }) + }) + .await + } +} diff --git a/server-rs/crates/spacetime-client/src/mapper/error_reports.rs b/server-rs/crates/spacetime-client/src/mapper/error_reports.rs new file mode 100644 index 000000000..acb85c0ef --- /dev/null +++ b/server-rs/crates/spacetime-client/src/mapper/error_reports.rs @@ -0,0 +1,125 @@ +use super::*; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ErrorReportRecord { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub review_status: String, + pub admin_note: Option, + pub created_at: String, + pub updated_at: String, +} + +pub struct ErrorReportCreateRecordInput { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub now_micros: i64, +} +pub struct ErrorReportListRecordInput { + pub status: Option, + pub fingerprint: Option, + pub source: Option, + pub limit: u32, + pub offset: u32, +} +pub struct ErrorReportUpdateRecordInput { + pub batch_id: String, + pub status: String, + pub note: Option, + pub now_micros: i64, +} + +fn map(s: ErrorReportSnapshot) -> ErrorReportRecord { + ErrorReportRecord { + batch_id: s.batch_id, + user_id: s.user_id, + submission_id: s.submission_id, + idempotency_key: s.idempotency_key, + object_key: s.object_key, + archive_sha256: s.archive_sha_256, + archive_size_bytes: s.archive_size_bytes, + event_count: s.event_count, + log_count: s.log_count, + first_fingerprint: s.first_fingerprint, + first_source: s.first_source, + review_status: s.review_status, + admin_note: s.admin_note, + created_at: format_timestamp_micros(s.created_at_micros), + updated_at: format_timestamp_micros(s.updated_at_micros), + } +} +pub(crate) fn map_error_report_result( + r: ErrorReportProcedureResult, +) -> Result { + if !r.ok { + return Err(SpacetimeClientError::procedure_failed(r.error_message)); + } + r.report + .map(map) + .ok_or_else(|| SpacetimeClientError::missing_snapshot("错误报告快照")) +} +pub(crate) fn map_error_report_list_result( + r: ErrorReportProcedureResult, +) -> Result<(Vec, u64), SpacetimeClientError> { + if !r.ok { + return Err(SpacetimeClientError::procedure_failed(r.error_message)); + } + Ok((r.reports.into_iter().map(map).collect(), r.total)) +} +impl From for ErrorReportCreateInput { + fn from(i: ErrorReportCreateRecordInput) -> Self { + Self { + batch_id: i.batch_id, + user_id: i.user_id, + submission_id: i.submission_id, + idempotency_key: i.idempotency_key, + object_key: i.object_key, + archive_sha_256: i.archive_sha256, + archive_size_bytes: i.archive_size_bytes, + event_count: i.event_count, + log_count: i.log_count, + first_fingerprint: i.first_fingerprint, + first_source: i.first_source, + now_micros: i.now_micros, + } + } +} +impl From for ErrorReportListInput { + fn from(i: ErrorReportListRecordInput) -> Self { + Self { + status: i.status, + fingerprint: i.fingerprint, + source: i.source, + limit: i.limit, + offset: i.offset, + } + } +} +impl From for ErrorReportUpdateInput { + fn from(i: ErrorReportUpdateRecordInput) -> Self { + Self { + batch_id: i.batch_id, + status: i.status, + note: i.note, + now_micros: i.now_micros, + } + } +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings.rs b/server-rs/crates/spacetime-client/src/module_bindings.rs index f6c9c3b9d..98c63e1c9 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings.rs @@ -197,6 +197,7 @@ pub mod create_editor_asset_and_return_procedure; pub mod create_editor_asset_folder_and_return_procedure; pub mod create_editor_project_and_return_procedure; pub mod create_editor_project_resource_and_return_procedure; +pub mod create_error_report_and_return_procedure; pub mod create_external_api_key_and_return_procedure; pub mod create_profile_recharge_order_and_return_procedure; pub mod creation_entry_config_table; @@ -241,6 +242,7 @@ pub mod delete_editor_agent_conversation_and_return_procedure; pub mod delete_editor_asset_and_return_procedure; pub mod delete_editor_asset_folder_and_return_procedure; pub mod delete_editor_project_and_return_procedure; +pub mod delete_error_report_and_return_procedure; pub mod editor_agent_conversation_create_input_type; pub mod editor_agent_conversation_delete_input_type; pub mod editor_agent_conversation_get_input_type; @@ -385,6 +387,15 @@ pub mod editor_spritesheet_slice_persisted_item_type; pub mod enqueue_external_generation_job_and_return_procedure; pub mod enqueue_profile_wallet_refund_outbox_and_return_procedure; pub mod ensure_analytics_date_dimension_for_date_reducer; +pub mod error_report_create_input_type; +pub mod error_report_delete_input_type; +pub mod error_report_get_input_type; +pub mod error_report_list_input_type; +pub mod error_report_procedure_result_type; +pub mod error_report_snapshot_type; +pub mod error_report_table; +pub mod error_report_type; +pub mod error_report_update_input_type; pub mod expire_profile_recharge_order_timer_reducer; pub mod export_auth_store_projection_from_tables_procedure; pub mod export_database_migration_to_file_procedure; @@ -446,6 +457,7 @@ pub mod get_editor_asset_library_and_return_procedure; pub mod get_editor_generation_pricing_config_and_return_procedure; pub mod get_editor_project_and_return_procedure; pub mod get_editor_showcase_campaign_config_and_return_procedure; +pub mod get_error_report_and_return_procedure; pub mod get_external_generation_job_and_return_procedure; pub mod get_external_generation_job_result_and_return_procedure; pub mod get_external_generation_job_summary_and_return_procedure; @@ -486,6 +498,7 @@ pub mod list_admin_accounts_and_return_procedure; pub mod list_asset_history_and_return_procedure; pub mod list_editor_agent_conversations_and_return_procedure; pub mod list_editor_projects_and_return_procedure; +pub mod list_error_reports_and_return_procedure; 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; @@ -849,6 +862,7 @@ pub mod update_editor_asset_and_return_procedure; pub mod update_editor_asset_folder_and_return_procedure; pub mod update_editor_project_resource_showcase_and_return_procedure; pub mod update_editor_showcase_asset_display_and_return_procedure; +pub mod update_error_report_and_return_procedure; pub mod update_external_generation_job_phase_and_return_procedure; pub mod upsert_editor_generation_pricing_config_and_return_procedure; pub mod upsert_editor_showcase_campaign_config_and_return_procedure; @@ -1071,6 +1085,7 @@ pub use create_editor_asset_and_return_procedure::create_editor_asset_and_return pub use create_editor_asset_folder_and_return_procedure::create_editor_asset_folder_and_return; pub use create_editor_project_and_return_procedure::create_editor_project_and_return; pub use create_editor_project_resource_and_return_procedure::create_editor_project_resource_and_return; +pub use create_error_report_and_return_procedure::create_error_report_and_return; pub use create_external_api_key_and_return_procedure::create_external_api_key_and_return; pub use create_profile_recharge_order_and_return_procedure::create_profile_recharge_order_and_return; pub use creation_entry_config_table::*; @@ -1115,6 +1130,7 @@ pub use delete_editor_agent_conversation_and_return_procedure::delete_editor_age pub use delete_editor_asset_and_return_procedure::delete_editor_asset_and_return; pub use delete_editor_asset_folder_and_return_procedure::delete_editor_asset_folder_and_return; pub use delete_editor_project_and_return_procedure::delete_editor_project_and_return; +pub use delete_error_report_and_return_procedure::delete_error_report_and_return; pub use editor_agent_conversation_create_input_type::EditorAgentConversationCreateInput; pub use editor_agent_conversation_delete_input_type::EditorAgentConversationDeleteInput; pub use editor_agent_conversation_get_input_type::EditorAgentConversationGetInput; @@ -1259,6 +1275,15 @@ pub use editor_spritesheet_slice_persisted_item_type::EditorSpritesheetSlicePers pub use enqueue_external_generation_job_and_return_procedure::enqueue_external_generation_job_and_return; pub use enqueue_profile_wallet_refund_outbox_and_return_procedure::enqueue_profile_wallet_refund_outbox_and_return; pub use ensure_analytics_date_dimension_for_date_reducer::ensure_analytics_date_dimension_for_date; +pub use error_report_create_input_type::ErrorReportCreateInput; +pub use error_report_delete_input_type::ErrorReportDeleteInput; +pub use error_report_get_input_type::ErrorReportGetInput; +pub use error_report_list_input_type::ErrorReportListInput; +pub use error_report_procedure_result_type::ErrorReportProcedureResult; +pub use error_report_snapshot_type::ErrorReportSnapshot; +pub use error_report_table::*; +pub use error_report_type::ErrorReport; +pub use error_report_update_input_type::ErrorReportUpdateInput; pub use expire_profile_recharge_order_timer_reducer::expire_profile_recharge_order_timer; pub use export_auth_store_projection_from_tables_procedure::export_auth_store_projection_from_tables; pub use export_database_migration_to_file_procedure::export_database_migration_to_file; @@ -1320,6 +1345,7 @@ pub use get_editor_asset_library_and_return_procedure::get_editor_asset_library_ pub use get_editor_generation_pricing_config_and_return_procedure::get_editor_generation_pricing_config_and_return; pub use get_editor_project_and_return_procedure::get_editor_project_and_return; pub use get_editor_showcase_campaign_config_and_return_procedure::get_editor_showcase_campaign_config_and_return; +pub use get_error_report_and_return_procedure::get_error_report_and_return; pub use get_external_generation_job_and_return_procedure::get_external_generation_job_and_return; pub use get_external_generation_job_result_and_return_procedure::get_external_generation_job_result_and_return; pub use get_external_generation_job_summary_and_return_procedure::get_external_generation_job_summary_and_return; @@ -1360,6 +1386,7 @@ pub use list_admin_accounts_and_return_procedure::list_admin_accounts_and_return 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; pub use list_editor_projects_and_return_procedure::list_editor_projects_and_return; +pub use list_error_reports_and_return_procedure::list_error_reports_and_return; pub use list_external_api_keys_and_return_procedure::list_external_api_keys_and_return; 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; @@ -1723,6 +1750,7 @@ pub use update_editor_asset_and_return_procedure::update_editor_asset_and_return pub use update_editor_asset_folder_and_return_procedure::update_editor_asset_folder_and_return; pub use update_editor_project_resource_showcase_and_return_procedure::update_editor_project_resource_showcase_and_return; pub use update_editor_showcase_asset_display_and_return_procedure::update_editor_showcase_asset_display_and_return; +pub use update_error_report_and_return_procedure::update_error_report_and_return; pub use update_external_generation_job_phase_and_return_procedure::update_external_generation_job_phase_and_return; pub use upsert_editor_generation_pricing_config_and_return_procedure::upsert_editor_generation_pricing_config_and_return; pub use upsert_editor_showcase_campaign_config_and_return_procedure::upsert_editor_showcase_campaign_config_and_return; @@ -1919,6 +1947,7 @@ pub struct DbUpdate { editor_showcase_asset: __sdk::TableUpdate, editor_showcase_asset_like: __sdk::TableUpdate, editor_showcase_campaign_config: __sdk::TableUpdate, + error_report: __sdk::TableUpdate, external_api_key: __sdk::TableUpdate, external_generation_job: __sdk::TableUpdate, external_generation_job_event: __sdk::TableUpdate, @@ -2211,6 +2240,9 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate { editor_showcase_campaign_config_table::parse_table_update(table_update)?, ) } + "error_report" => db_update + .error_report + .append(error_report_table::parse_table_update(table_update)?), "external_api_key" => db_update .external_api_key .append(external_api_key_table::parse_table_update(table_update)?), @@ -2812,6 +2844,9 @@ impl __sdk::DbUpdate for DbUpdate { &self.editor_showcase_campaign_config, ) .with_updates_by_pk(|row| &row.config_id); + diff.error_report = cache + .apply_diff_to_table::("error_report", &self.error_report) + .with_updates_by_pk(|row| &row.batch_id); diff.external_api_key = cache .apply_diff_to_table::("external_api_key", &self.external_api_key) .with_updates_by_pk(|row| &row.key_id); @@ -3433,6 +3468,9 @@ impl __sdk::DbUpdate for DbUpdate { "editor_showcase_campaign_config" => db_update .editor_showcase_campaign_config .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), + "error_report" => db_update + .error_report + .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), "external_api_key" => db_update .external_api_key .append(__sdk::parse_row_list_as_inserts(table_rows.rows)?), @@ -3866,6 +3904,9 @@ impl __sdk::DbUpdate for DbUpdate { "editor_showcase_campaign_config" => db_update .editor_showcase_campaign_config .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), + "error_report" => db_update + .error_report + .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), "external_api_key" => db_update .external_api_key .append(__sdk::parse_row_list_as_deletes(table_rows.rows)?), @@ -4193,6 +4234,7 @@ pub struct AppliedDiff<'r> { editor_showcase_asset: __sdk::TableAppliedDiff<'r, EditorShowcaseAsset>, editor_showcase_asset_like: __sdk::TableAppliedDiff<'r, EditorShowcaseAssetLike>, editor_showcase_campaign_config: __sdk::TableAppliedDiff<'r, EditorShowcaseCampaignConfig>, + error_report: __sdk::TableAppliedDiff<'r, ErrorReport>, external_api_key: __sdk::TableAppliedDiff<'r, ExternalApiKey>, external_generation_job: __sdk::TableAppliedDiff<'r, ExternalGenerationJob>, external_generation_job_event: __sdk::TableAppliedDiff<'r, ExternalGenerationJobEvent>, @@ -4568,6 +4610,11 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { &self.editor_showcase_campaign_config, event, ); + callbacks.invoke_table_row_callbacks::( + "error_report", + &self.error_report, + event, + ); callbacks.invoke_table_row_callbacks::( "external_api_key", &self.external_api_key, @@ -5231,19 +5278,19 @@ impl __sdk::SubscriptionHandle for SubscriptionHandle { /// either a [`DbConnection`] or an [`EventContext`] and operate on either. pub trait RemoteDbContext: __sdk::DbContext< - DbView = RemoteTables, - Reducers = RemoteReducers, - SubscriptionBuilder = __sdk::SubscriptionBuilder, - > + DbView = RemoteTables, + Reducers = RemoteReducers, + SubscriptionBuilder = __sdk::SubscriptionBuilder, +> { } impl< - Ctx: __sdk::DbContext< + Ctx: __sdk::DbContext< DbView = RemoteTables, Reducers = RemoteReducers, SubscriptionBuilder = __sdk::SubscriptionBuilder, >, -> RemoteDbContext for Ctx + > RemoteDbContext for Ctx { } @@ -5692,6 +5739,7 @@ impl __sdk::SpacetimeModule for RemoteModule { editor_showcase_asset_table::register_table(client_cache); editor_showcase_asset_like_table::register_table(client_cache); editor_showcase_campaign_config_table::register_table(client_cache); + error_report_table::register_table(client_cache); external_api_key_table::register_table(client_cache); external_generation_job_table::register_table(client_cache); external_generation_job_event_table::register_table(client_cache); @@ -5834,6 +5882,7 @@ impl __sdk::SpacetimeModule for RemoteModule { "editor_showcase_asset", "editor_showcase_asset_like", "editor_showcase_campaign_config", + "error_report", "external_api_key", "external_generation_job", "external_generation_job_event", diff --git a/server-rs/crates/spacetime-client/src/module_bindings/create_error_report_and_return_procedure.rs b/server-rs/crates/spacetime-client/src/module_bindings/create_error_report_and_return_procedure.rs new file mode 100644 index 000000000..cead7fda8 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/create_error_report_and_return_procedure.rs @@ -0,0 +1,59 @@ +// 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::error_report_create_input_type::ErrorReportCreateInput; +use super::error_report_procedure_result_type::ErrorReportProcedureResult; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +struct CreateErrorReportAndReturnArgs { + pub input: ErrorReportCreateInput, +} + +impl __sdk::InModule for CreateErrorReportAndReturnArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the procedure `create_error_report_and_return`. +/// +/// Implemented for [`super::RemoteProcedures`]. +pub trait create_error_report_and_return { + fn create_error_report_and_return(&self, input: ErrorReportCreateInput) { + self.create_error_report_and_return_then(input, |_, _| {}); + } + + fn create_error_report_and_return_then( + &self, + input: ErrorReportCreateInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ); +} + +impl create_error_report_and_return for super::RemoteProcedures { + fn create_error_report_and_return_then( + &self, + input: ErrorReportCreateInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ) { + self.imp + .invoke_procedure_with_callback::<_, ErrorReportProcedureResult>( + "create_error_report_and_return", + CreateErrorReportAndReturnArgs { input }, + __callback, + ); + } +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/delete_error_report_and_return_procedure.rs b/server-rs/crates/spacetime-client/src/module_bindings/delete_error_report_and_return_procedure.rs new file mode 100644 index 000000000..f4070c42a --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/delete_error_report_and_return_procedure.rs @@ -0,0 +1,59 @@ +// 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::error_report_delete_input_type::ErrorReportDeleteInput; +use super::error_report_procedure_result_type::ErrorReportProcedureResult; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +struct DeleteErrorReportAndReturnArgs { + pub input: ErrorReportDeleteInput, +} + +impl __sdk::InModule for DeleteErrorReportAndReturnArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the procedure `delete_error_report_and_return`. +/// +/// Implemented for [`super::RemoteProcedures`]. +pub trait delete_error_report_and_return { + fn delete_error_report_and_return(&self, input: ErrorReportDeleteInput) { + self.delete_error_report_and_return_then(input, |_, _| {}); + } + + fn delete_error_report_and_return_then( + &self, + input: ErrorReportDeleteInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ); +} + +impl delete_error_report_and_return for super::RemoteProcedures { + fn delete_error_report_and_return_then( + &self, + input: ErrorReportDeleteInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ) { + self.imp + .invoke_procedure_with_callback::<_, ErrorReportProcedureResult>( + "delete_error_report_and_return", + DeleteErrorReportAndReturnArgs { input }, + __callback, + ); + } +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_create_input_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_create_input_type.rs new file mode 100644 index 000000000..8f111faa6 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_create_input_type.rs @@ -0,0 +1,26 @@ +// 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 ErrorReportCreateInput { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha_256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub now_micros: i64, +} + +impl __sdk::InModule for ErrorReportCreateInput { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_delete_input_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_delete_input_type.rs new file mode 100644 index 000000000..11babf06f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_delete_input_type.rs @@ -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 ErrorReportDeleteInput { + pub batch_id: String, +} + +impl __sdk::InModule for ErrorReportDeleteInput { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_get_input_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_get_input_type.rs new file mode 100644 index 000000000..97d9aed59 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_get_input_type.rs @@ -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 ErrorReportGetInput { + pub batch_id: String, +} + +impl __sdk::InModule for ErrorReportGetInput { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_list_input_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_list_input_type.rs new file mode 100644 index 000000000..47d5bb9de --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_list_input_type.rs @@ -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}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct ErrorReportListInput { + pub status: Option, + pub fingerprint: Option, + pub source: Option, + pub limit: u32, + pub offset: u32, +} + +impl __sdk::InModule for ErrorReportListInput { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_procedure_result_type.rs new file mode 100644 index 000000000..61cd14056 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_procedure_result_type.rs @@ -0,0 +1,21 @@ +// 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::error_report_snapshot_type::ErrorReportSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct ErrorReportProcedureResult { + pub ok: bool, + pub report: Option, + pub reports: Vec, + pub total: u64, + pub error_message: Option, +} + +impl __sdk::InModule for ErrorReportProcedureResult { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_snapshot_type.rs new file mode 100644 index 000000000..0bc2c9d2f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_snapshot_type.rs @@ -0,0 +1,29 @@ +// 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 ErrorReportSnapshot { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha_256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub review_status: String, + pub admin_note: Option, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for ErrorReportSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_table.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_table.rs new file mode 100644 index 000000000..916e6b2aa --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_table.rs @@ -0,0 +1,259 @@ +// 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::error_report_type::ErrorReport; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `error_report`. +/// +/// Obtain a handle from the [`ErrorReportTableAccess::error_report`] method on [`super::RemoteTables`], +/// like `ctx.db.error_report()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.error_report().on_insert(...)`. +pub struct ErrorReportTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +/// Lifetime-aware accessor marker for the table `error_report`. +pub struct ErrorReportTableAccessor; + +impl __sdk::TableAccessor for ErrorReportTableAccessor { + type Row = ErrorReport; + type Handle<'db> = ErrorReportTableHandle<'db>; + + fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> { + db.error_report() + } +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `error_report`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait ErrorReportTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`ErrorReportTableHandle`], which mediates access to the table `error_report`. + fn error_report(&self) -> ErrorReportTableHandle<'_>; +} + +impl ErrorReportTableAccess for super::RemoteTables { + fn error_report(&self) -> ErrorReportTableHandle<'_> { + ErrorReportTableHandle { + imp: self.imp.get_table::("error_report"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct ErrorReportInsertCallbackId(__sdk::CallbackId); +pub struct ErrorReportDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableLike for ErrorReportTableHandle<'ctx> { + type Row = ErrorReport; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } +} + +impl<'ctx> __sdk::Table for ErrorReportTableHandle<'ctx> { + type Row = ErrorReport; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = ErrorReportInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ErrorReportInsertCallbackId { + ErrorReportInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: ErrorReportInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = ErrorReportDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ErrorReportDeleteCallbackId { + ErrorReportDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: ErrorReportDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +impl<'ctx> __sdk::WithInsert for ErrorReportTableHandle<'ctx> { + type InsertCallbackId = ErrorReportInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ErrorReportInsertCallbackId { + ErrorReportInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: ErrorReportInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } +} + +impl<'ctx> __sdk::WithDelete for ErrorReportTableHandle<'ctx> { + type DeleteCallbackId = ErrorReportDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ErrorReportDeleteCallbackId { + ErrorReportDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: ErrorReportDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +pub struct ErrorReportUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for ErrorReportTableHandle<'ctx> { + type UpdateCallbackId = ErrorReportUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> ErrorReportUpdateCallbackId { + ErrorReportUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: ErrorReportUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +impl<'ctx> __sdk::WithUpdate for ErrorReportTableHandle<'ctx> { + type UpdateCallbackId = ErrorReportUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> ErrorReportUpdateCallbackId { + ErrorReportUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: ErrorReportUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +/// Access to the `batch_id` unique index on the table `error_report`, +/// which allows point queries on the field of the same name +/// via the [`ErrorReportBatchIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.error_report().batch_id().find(...)`. +pub struct ErrorReportBatchIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> ErrorReportTableHandle<'ctx> { + /// Get a handle on the `batch_id` unique index on the table `error_report`. + pub fn batch_id(&self) -> ErrorReportBatchIdUnique<'ctx> { + ErrorReportBatchIdUnique { + imp: self.imp.get_unique_constraint::("batch_id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> ErrorReportBatchIdUnique<'ctx> { + /// Find the subscribed row whose `batch_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 { + self.imp.find(col_val) + } +} + +/// Access to the `idempotency_key` unique index on the table `error_report`, +/// which allows point queries on the field of the same name +/// via the [`ErrorReportIdempotencyKeyUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.error_report().idempotency_key().find(...)`. +pub struct ErrorReportIdempotencyKeyUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> ErrorReportTableHandle<'ctx> { + /// Get a handle on the `idempotency_key` unique index on the table `error_report`. + pub fn idempotency_key(&self) -> ErrorReportIdempotencyKeyUnique<'ctx> { + ErrorReportIdempotencyKeyUnique { + imp: self.imp.get_unique_constraint::("idempotency_key"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> ErrorReportIdempotencyKeyUnique<'ctx> { + /// Find the subscribed row whose `idempotency_key` 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 { + self.imp.find(col_val) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("error_report"); + _table.add_unique_constraint::("batch_id", |row| &row.batch_id); + _table.add_unique_constraint::("idempotency_key", |row| &row.idempotency_key); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `ErrorReport`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait error_reportQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `ErrorReport`. + fn error_report(&self) -> __sdk::__query_builder::Table; +} + +impl error_reportQueryTableAccess for __sdk::QueryTableAccessor { + fn error_report(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("error_report") + } +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_type.rs new file mode 100644 index 000000000..300de9bf5 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_type.rs @@ -0,0 +1,97 @@ +// 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 ErrorReport { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha_256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub review_status: String, + pub admin_note: Option, + pub created_at: __sdk::Timestamp, + pub updated_at: __sdk::Timestamp, +} + +impl __sdk::InModule for ErrorReport { + type Module = super::RemoteModule; +} + +/// Column accessor struct for the table `ErrorReport`. +/// +/// Provides typed access to columns for query building. +pub struct ErrorReportCols { + pub batch_id: __sdk::__query_builder::Col, + pub user_id: __sdk::__query_builder::Col, + pub submission_id: __sdk::__query_builder::Col, + pub idempotency_key: __sdk::__query_builder::Col, + pub object_key: __sdk::__query_builder::Col, + pub archive_sha_256: __sdk::__query_builder::Col, + pub archive_size_bytes: __sdk::__query_builder::Col, + pub event_count: __sdk::__query_builder::Col, + pub log_count: __sdk::__query_builder::Col, + pub first_fingerprint: __sdk::__query_builder::Col>, + pub first_source: __sdk::__query_builder::Col>, + pub review_status: __sdk::__query_builder::Col, + pub admin_note: __sdk::__query_builder::Col>, + pub created_at: __sdk::__query_builder::Col, + pub updated_at: __sdk::__query_builder::Col, +} + +impl __sdk::__query_builder::HasCols for ErrorReport { + type Cols = ErrorReportCols; + fn cols(table_name: &'static str) -> Self::Cols { + ErrorReportCols { + batch_id: __sdk::__query_builder::Col::new(table_name, "batch_id"), + user_id: __sdk::__query_builder::Col::new(table_name, "user_id"), + submission_id: __sdk::__query_builder::Col::new(table_name, "submission_id"), + idempotency_key: __sdk::__query_builder::Col::new(table_name, "idempotency_key"), + object_key: __sdk::__query_builder::Col::new(table_name, "object_key"), + archive_sha_256: __sdk::__query_builder::Col::new(table_name, "archive_sha_256"), + archive_size_bytes: __sdk::__query_builder::Col::new(table_name, "archive_size_bytes"), + event_count: __sdk::__query_builder::Col::new(table_name, "event_count"), + log_count: __sdk::__query_builder::Col::new(table_name, "log_count"), + first_fingerprint: __sdk::__query_builder::Col::new(table_name, "first_fingerprint"), + first_source: __sdk::__query_builder::Col::new(table_name, "first_source"), + review_status: __sdk::__query_builder::Col::new(table_name, "review_status"), + admin_note: __sdk::__query_builder::Col::new(table_name, "admin_note"), + created_at: __sdk::__query_builder::Col::new(table_name, "created_at"), + updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"), + } + } +} + +/// Indexed column accessor struct for the table `ErrorReport`. +/// +/// Provides typed access to indexed columns for query building. +pub struct ErrorReportIxCols { + pub batch_id: __sdk::__query_builder::IxCol, + pub created_at: __sdk::__query_builder::IxCol, + pub idempotency_key: __sdk::__query_builder::IxCol, + pub review_status: __sdk::__query_builder::IxCol, +} + +impl __sdk::__query_builder::HasIxCols for ErrorReport { + type IxCols = ErrorReportIxCols; + fn ix_cols(table_name: &'static str) -> Self::IxCols { + ErrorReportIxCols { + batch_id: __sdk::__query_builder::IxCol::new(table_name, "batch_id"), + created_at: __sdk::__query_builder::IxCol::new(table_name, "created_at"), + idempotency_key: __sdk::__query_builder::IxCol::new(table_name, "idempotency_key"), + review_status: __sdk::__query_builder::IxCol::new(table_name, "review_status"), + } + } +} + +impl __sdk::__query_builder::CanBeLookupTable for ErrorReport {} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/error_report_update_input_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/error_report_update_input_type.rs new file mode 100644 index 000000000..d84109513 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/error_report_update_input_type.rs @@ -0,0 +1,18 @@ +// 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 ErrorReportUpdateInput { + pub batch_id: String, + pub status: String, + pub note: Option, + pub now_micros: i64, +} + +impl __sdk::InModule for ErrorReportUpdateInput { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/get_error_report_and_return_procedure.rs b/server-rs/crates/spacetime-client/src/module_bindings/get_error_report_and_return_procedure.rs new file mode 100644 index 000000000..5bd9d91ee --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/get_error_report_and_return_procedure.rs @@ -0,0 +1,59 @@ +// 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::error_report_get_input_type::ErrorReportGetInput; +use super::error_report_procedure_result_type::ErrorReportProcedureResult; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +struct GetErrorReportAndReturnArgs { + pub input: ErrorReportGetInput, +} + +impl __sdk::InModule for GetErrorReportAndReturnArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the procedure `get_error_report_and_return`. +/// +/// Implemented for [`super::RemoteProcedures`]. +pub trait get_error_report_and_return { + fn get_error_report_and_return(&self, input: ErrorReportGetInput) { + self.get_error_report_and_return_then(input, |_, _| {}); + } + + fn get_error_report_and_return_then( + &self, + input: ErrorReportGetInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ); +} + +impl get_error_report_and_return for super::RemoteProcedures { + fn get_error_report_and_return_then( + &self, + input: ErrorReportGetInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ) { + self.imp + .invoke_procedure_with_callback::<_, ErrorReportProcedureResult>( + "get_error_report_and_return", + GetErrorReportAndReturnArgs { input }, + __callback, + ); + } +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/list_error_reports_and_return_procedure.rs b/server-rs/crates/spacetime-client/src/module_bindings/list_error_reports_and_return_procedure.rs new file mode 100644 index 000000000..087327169 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/list_error_reports_and_return_procedure.rs @@ -0,0 +1,59 @@ +// 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::error_report_list_input_type::ErrorReportListInput; +use super::error_report_procedure_result_type::ErrorReportProcedureResult; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +struct ListErrorReportsAndReturnArgs { + pub input: ErrorReportListInput, +} + +impl __sdk::InModule for ListErrorReportsAndReturnArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the procedure `list_error_reports_and_return`. +/// +/// Implemented for [`super::RemoteProcedures`]. +pub trait list_error_reports_and_return { + fn list_error_reports_and_return(&self, input: ErrorReportListInput) { + self.list_error_reports_and_return_then(input, |_, _| {}); + } + + fn list_error_reports_and_return_then( + &self, + input: ErrorReportListInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ); +} + +impl list_error_reports_and_return for super::RemoteProcedures { + fn list_error_reports_and_return_then( + &self, + input: ErrorReportListInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ) { + self.imp + .invoke_procedure_with_callback::<_, ErrorReportProcedureResult>( + "list_error_reports_and_return", + ListErrorReportsAndReturnArgs { input }, + __callback, + ); + } +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/update_error_report_and_return_procedure.rs b/server-rs/crates/spacetime-client/src/module_bindings/update_error_report_and_return_procedure.rs new file mode 100644 index 000000000..5ce804a62 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/update_error_report_and_return_procedure.rs @@ -0,0 +1,59 @@ +// 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::error_report_procedure_result_type::ErrorReportProcedureResult; +use super::error_report_update_input_type::ErrorReportUpdateInput; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +struct UpdateErrorReportAndReturnArgs { + pub input: ErrorReportUpdateInput, +} + +impl __sdk::InModule for UpdateErrorReportAndReturnArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the procedure `update_error_report_and_return`. +/// +/// Implemented for [`super::RemoteProcedures`]. +pub trait update_error_report_and_return { + fn update_error_report_and_return(&self, input: ErrorReportUpdateInput) { + self.update_error_report_and_return_then(input, |_, _| {}); + } + + fn update_error_report_and_return_then( + &self, + input: ErrorReportUpdateInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ); +} + +impl update_error_report_and_return for super::RemoteProcedures { + fn update_error_report_and_return_then( + &self, + input: ErrorReportUpdateInput, + + __callback: impl FnOnce( + &super::ProcedureEventContext, + Result, + ) + Send + + 'static, + ) { + self.imp + .invoke_procedure_with_callback::<_, ErrorReportProcedureResult>( + "update_error_report_and_return", + UpdateErrorReportAndReturnArgs { input }, + __callback, + ); + } +} diff --git a/server-rs/crates/spacetime-module/src/active.rs b/server-rs/crates/spacetime-module/src/active.rs index 415a2c742..2afbc3464 100644 --- a/server-rs/crates/spacetime-module/src/active.rs +++ b/server-rs/crates/spacetime-module/src/active.rs @@ -23,6 +23,8 @@ mod big_fish; mod custom_world; mod editor_agent_storage; mod editor_project_storage; +#[path = "error_report.rs"] +mod error_reports_schema; mod external_api_key_storage; mod external_generation; #[path = "legacy_schema/gameplay.rs"] @@ -54,6 +56,7 @@ pub use big_fish::*; pub use custom_world::*; pub use editor_agent_storage::*; pub use editor_project_storage::*; +pub use error_reports_schema::*; pub use external_api_key_storage::*; pub use external_generation::*; pub use gameplay::*; diff --git a/server-rs/crates/spacetime-module/src/error_report.rs b/server-rs/crates/spacetime-module/src/error_report.rs new file mode 100644 index 000000000..1c3a4fc6d --- /dev/null +++ b/server-rs/crates/spacetime-module/src/error_report.rs @@ -0,0 +1,357 @@ +use crate::*; + +const MAX_FIELD_CHARS: usize = 512; +const MAX_NOTE_CHARS: usize = 2_000; + +#[spacetimedb::table( + accessor = error_report, + index(accessor = by_error_report_user_submission, btree(columns = [user_id, submission_id])), + index(accessor = by_error_report_created_at, btree(columns = [created_at])), + index(accessor = by_error_report_review_status, btree(columns = [review_status])) +)] +#[derive(Clone)] +pub struct ErrorReport { + #[primary_key] + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + #[unique] + pub idempotency_key: String, + pub object_key: String, + pub archive_sha256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub review_status: String, + pub admin_note: Option, + pub created_at: Timestamp, + pub updated_at: Timestamp, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportCreateInput { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub now_micros: i64, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportListInput { + pub status: Option, + pub fingerprint: Option, + pub source: Option, + pub limit: u32, + pub offset: u32, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportGetInput { + pub batch_id: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportUpdateInput { + pub batch_id: String, + pub status: String, + pub note: Option, + pub now_micros: i64, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportDeleteInput { + pub batch_id: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportSnapshot { + pub batch_id: String, + pub user_id: String, + pub submission_id: String, + pub idempotency_key: String, + pub object_key: String, + pub archive_sha256: String, + pub archive_size_bytes: u64, + pub event_count: u32, + pub log_count: u32, + pub first_fingerprint: Option, + pub first_source: Option, + pub review_status: String, + pub admin_note: Option, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +pub struct ErrorReportProcedureResult { + pub ok: bool, + pub report: Option, + pub reports: Vec, + pub total: u64, + pub error_message: Option, +} + +fn error(message: impl Into) -> ErrorReportProcedureResult { + ErrorReportProcedureResult { + ok: false, + report: None, + reports: Vec::new(), + total: 0, + error_message: Some(message.into()), + } +} + +fn validate_text(value: &str, field: &str) -> Result { + let value = value.trim(); + if value.is_empty() || value.chars().count() > MAX_FIELD_CHARS { + return Err(format!("error_report.{field} 无效")); + } + Ok(value.to_string()) +} + +fn snapshot(row: &ErrorReport) -> ErrorReportSnapshot { + ErrorReportSnapshot { + batch_id: row.batch_id.clone(), + user_id: row.user_id.clone(), + submission_id: row.submission_id.clone(), + idempotency_key: row.idempotency_key.clone(), + object_key: row.object_key.clone(), + archive_sha256: row.archive_sha256.clone(), + archive_size_bytes: row.archive_size_bytes, + event_count: row.event_count, + log_count: row.log_count, + first_fingerprint: row.first_fingerprint.clone(), + first_source: row.first_source.clone(), + review_status: row.review_status.clone(), + admin_note: row.admin_note.clone(), + created_at_micros: row.created_at.to_micros_since_unix_epoch(), + updated_at_micros: row.updated_at.to_micros_since_unix_epoch(), + } +} + +#[spacetimedb::procedure] +pub fn create_error_report_and_return( + ctx: &mut ProcedureContext, + input: ErrorReportCreateInput, +) -> ErrorReportProcedureResult { + match ctx.try_with_tx(|tx| { + let batch_id = validate_text(&input.batch_id, "batch_id")?; + let user_id = validate_text(&input.user_id, "user_id")?; + let submission_id = validate_text(&input.submission_id, "submission_id")?; + let idempotency_key = validate_text(&input.idempotency_key, "idempotency_key")?; + let object_key = validate_text(&input.object_key, "object_key")?; + let archive_sha256 = validate_text(&input.archive_sha256, "archive_sha256")?; + if let Some(existing) = tx + .db + .error_report() + .by_error_report_user_submission() + .filter((user_id.as_str(), submission_id.as_str())) + .next() + { + return Ok(snapshot(&existing)); + } + if tx + .db + .error_report() + .idempotency_key() + .find(&idempotency_key) + .is_some() + { + return Err("错误报告提交幂等键冲突".to_string()); + } + if tx.db.error_report().batch_id().find(&batch_id).is_some() { + return Err("错误报告 batch_id 已存在".to_string()); + } + let now = Timestamp::from_micros_since_unix_epoch(input.now_micros); + tx.db.error_report().insert(ErrorReport { + batch_id, + user_id, + submission_id, + idempotency_key, + object_key, + archive_sha256, + archive_size_bytes: input.archive_size_bytes, + event_count: input.event_count, + log_count: input.log_count, + first_fingerprint: input.first_fingerprint.clone(), + first_source: input.first_source.clone(), + review_status: "new".to_string(), + admin_note: None, + created_at: now, + updated_at: now, + }); + tx.db + .error_report() + .batch_id() + .find(&input.batch_id) + .map(|row| snapshot(&row)) + .ok_or_else(|| "错误报告写入后读取失败".to_string()) + }) { + Ok(report) => ErrorReportProcedureResult { + ok: true, + report: Some(report), + reports: Vec::new(), + total: 1, + error_message: None, + }, + Err(message) => error(message), + } +} + +#[spacetimedb::procedure] +pub fn get_error_report_and_return( + ctx: &mut ProcedureContext, + input: ErrorReportGetInput, +) -> ErrorReportProcedureResult { + match ctx.try_with_tx(|tx| { + tx.db + .error_report() + .batch_id() + .find(&input.batch_id) + .map(|row| snapshot(&row)) + .ok_or_else(|| "错误报告不存在".to_string()) + }) { + Ok(report) => ErrorReportProcedureResult { + ok: true, + report: Some(report), + reports: Vec::new(), + total: 1, + error_message: None, + }, + Err(message) => error(message), + } +} + +#[spacetimedb::procedure] +pub fn list_error_reports_and_return( + ctx: &mut ProcedureContext, + input: ErrorReportListInput, +) -> ErrorReportProcedureResult { + match ctx.try_with_tx(|tx| { + let mut rows = tx + .db + .error_report() + .iter() + .filter(|row| { + input + .status + .as_deref() + .is_none_or(|v| v == row.review_status) + }) + .filter(|row| { + input + .fingerprint + .as_deref() + .is_none_or(|v| row.first_fingerprint.as_deref() == Some(v)) + }) + .filter(|row| { + input + .source + .as_deref() + .is_none_or(|v| row.first_source.as_deref() == Some(v)) + }) + .collect::>(); + rows.sort_by(|left, right| { + right + .created_at + .cmp(&left.created_at) + .then_with(|| right.batch_id.cmp(&left.batch_id)) + }); + let total = rows.len() as u64; + let limit = input.limit.clamp(1, 500) as usize; + let offset = input.offset as usize; + let reports = rows + .into_iter() + .skip(offset) + .take(limit) + .map(|row| snapshot(&row)) + .collect::>(); + Ok::<(Vec, u64), String>((reports, total)) + }) { + Ok((reports, total)) => ErrorReportProcedureResult { + ok: true, + report: None, + reports, + total, + error_message: None, + }, + Err(message) => error(message), + } +} + +#[spacetimedb::procedure] +pub fn update_error_report_and_return( + ctx: &mut ProcedureContext, + input: ErrorReportUpdateInput, +) -> ErrorReportProcedureResult { + match ctx.try_with_tx(|tx| { + if !matches!(input.status.as_str(), "new" | "in-progress" | "resolved") { + return Err("状态必须是 new、in-progress 或 resolved".to_string()); + } + let row = tx + .db + .error_report() + .batch_id() + .find(&input.batch_id) + .ok_or_else(|| "错误报告不存在".to_string())?; + let note = input + .note + .clone() + .map(|value| value.chars().take(MAX_NOTE_CHARS).collect::()); + let updated = ErrorReport { + review_status: input.status.clone(), + admin_note: note, + updated_at: Timestamp::from_micros_since_unix_epoch(input.now_micros), + ..row.clone() + }; + tx.db.error_report().batch_id().delete(&row.batch_id); + tx.db.error_report().insert(updated.clone()); + Ok(snapshot(&updated)) + }) { + Ok(report) => ErrorReportProcedureResult { + ok: true, + report: Some(report), + reports: Vec::new(), + total: 1, + error_message: None, + }, + Err(message) => error(message), + } +} + +#[spacetimedb::procedure] +pub fn delete_error_report_and_return( + ctx: &mut ProcedureContext, + input: ErrorReportDeleteInput, +) -> ErrorReportProcedureResult { + match ctx.try_with_tx(|tx| { + let row = tx + .db + .error_report() + .batch_id() + .find(&input.batch_id) + .ok_or_else(|| "错误报告不存在".to_string())?; + let snapshot = snapshot(&row); + tx.db.error_report().batch_id().delete(&row.batch_id); + Ok::(snapshot) + }) { + Ok(report) => ErrorReportProcedureResult { + ok: true, + report: Some(report), + reports: Vec::new(), + total: 1, + error_message: None, + }, + Err(message) => error(message), + } +} diff --git a/server-rs/crates/spacetime-module/src/migration.rs b/server-rs/crates/spacetime-module/src/migration.rs index 32e02063c..0bdd92d3c 100644 --- a/server-rs/crates/spacetime-module/src/migration.rs +++ b/server-rs/crates/spacetime-module/src/migration.rs @@ -250,6 +250,7 @@ macro_rules! migration_tables { asset_entity_binding, asset_event, external_api_key, + error_report, editor_agent_conversation, editor_project, editor_canvas,