use serde::{Deserialize, Serialize}; use serde_json::Value; // 管理后台协议统一收口在 shared-contracts,避免页面脚本和 Rust handler 各自手拼字段。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminLoginRequest { pub username: String, pub password: String, } // 登录成功后返回管理员访问令牌与基础会话信息。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminLoginResponse { pub token: String, pub admin: AdminSessionPayload, } // 管理员会话只暴露页面展示和鉴权调试所需的最小字段。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminSessionPayload { pub subject: String, pub username: String, pub display_name: String, pub roles: Vec, pub issued_at: String, pub expires_at: String, } // 页面恢复登录态时读取当前管理员会话。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminMeResponse { pub admin: AdminSessionPayload, } // 后台概览统一返回服务信息与数据库信息两块,前端不再额外拼装。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct AdminOverviewResponse { pub service: AdminServiceOverviewPayload, pub database: AdminDatabaseOverviewPayload, } // 服务概览描述当前 api-server 与 SpacetimeDB 连接配置。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminServiceOverviewPayload { pub bind_host: String, pub bind_port: u16, pub jwt_issuer: String, pub admin_enabled: bool, pub spacetime_server_url: String, pub spacetime_database: String, } // 数据库概览返回真实数据库元信息、表清单与统计错误。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminDatabaseOverviewPayload { pub database_identity: Option, pub owner_identity: Option, pub host_type: Option, pub schema_table_names: Vec, pub table_stats: Vec, pub fetch_errors: Vec, } // 单表统计允许成功和失败并存,避免某张表失败导致整页概览不可用。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminDatabaseTableStatPayload { pub table_name: String, pub row_count: Option, pub error_message: Option, } // 后台表清单独立用于“表查询”页,避免页面必须先拉完整总览。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminDatabaseTableListResponse { pub tables: Vec, pub fetch_errors: Vec, } // 后台通用表查询参数,用户输入不进入 SQL,只在 API Server 内存中过滤。 #[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminDatabaseTableRowsQuery { pub limit: Option, pub search: Option, pub filters: Option, } // 后台通用表查询响应,cells 使用列名映射,raw 保留原始行便于详情排障。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct AdminDatabaseTableRowsResponse { pub table_name: String, pub columns: Vec, pub rows: Vec, pub total_returned: usize, pub limit: u32, } // 单行查询结果,值统一用 JSON 承载以兼容不同表字段类型。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct AdminDatabaseTableRowPayload { pub cells: Value, pub raw: Value, } // 调试请求只允许同源路径、受控请求头和有限请求体。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct AdminDebugHttpRequest { pub method: String, pub path: String, pub headers: Option>, pub body: Option, } // 调试请求头使用显式结构,避免页面直接塞任意对象。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminDebugHeaderInput { pub name: String, pub value: String, } // 调试响应回显状态、响应头与文本/JSON 预览,便于后台排查接口问题。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct AdminDebugHttpResponse { pub status: u16, pub status_text: String, pub headers: Vec, pub body_text: String, pub body_json: Option, } // 后台埋点明细查询参数只保留运营筛选需要的只读字段。 #[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminTrackingEventListQuery { pub event_key: Option, pub user_id: Option, pub scope_kind: Option, pub scope_id: Option, pub limit: Option, } // 单条埋点原始事件明细,字段与 tracking_event 表一一对应并补充事件名称。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminTrackingEventEntryPayload { pub event_id: String, pub event_key: String, pub event_title: String, pub scope_kind: String, pub scope_id: String, pub day_key: i64, pub user_id: Option, pub owner_user_id: Option, pub profile_id: Option, pub module_key: Option, pub metadata_json: String, pub occurred_at: String, } // 后台埋点明细列表响应,前端导出 Excel 时直接使用 entries。 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct AdminTrackingEventListResponse { pub entries: Vec, }