Files
Genarrative/server-rs/crates/shared-contracts/src/admin.rs
T

281 lines
9.5 KiB
Rust

use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::creation_entry_config::{CreationEntryEventBannerResponse, UnifiedCreationSpecResponse};
// 管理后台协议统一收口在 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 AdminCreationEntryConfigResponse {
pub entries: Vec<AdminCreationEntryTypeConfigPayload>,
/// 底部加号创作入口页的后台公告列表。
pub event_banners: Vec<CreationEntryEventBannerResponse>,
}
/// 后台单个创作入口开关配置。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminCreationEntryTypeConfigPayload {
pub id: String,
pub title: String,
pub subtitle: String,
pub badge: String,
pub image_src: String,
pub visible: bool,
pub open: bool,
pub sort_order: i32,
pub category_id: String,
pub category_label: String,
pub category_sort_order: i32,
pub updated_at_micros: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub unified_creation_spec: Option<UnifiedCreationSpecResponse>,
}
/// 后台保存创作入口开关配置请求。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminUpsertCreationEntryTypeConfigRequest {
pub id: String,
pub title: String,
pub subtitle: String,
pub badge: String,
pub image_src: String,
pub visible: bool,
pub open: bool,
pub sort_order: i32,
pub category_id: String,
pub category_label: String,
pub category_sort_order: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub unified_creation_spec: Option<UnifiedCreationSpecResponse>,
}
/// 后台保存创作入口公告表单序列化结果请求。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminUpsertCreationEntryEventBannersRequest {
/// 传输字段沿用既有契约,内容由后台标题 / HTML 表单生成。
pub event_banners_json: String,
}
/// 后台作品可见性列表项。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminWorkVisibilityEntryPayload {
pub source_type: String,
pub work_id: String,
pub profile_id: String,
pub source_session_id: Option<String>,
pub public_work_code: String,
pub owner_user_id: String,
pub author_display_name: String,
pub title: String,
pub subtitle: String,
pub cover_image_src: Option<String>,
pub visible: bool,
pub published_at_micros: Option<i64>,
pub updated_at_micros: i64,
}
/// 后台作品可见性列表响应。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminWorkVisibilityListResponse {
pub entries: Vec<AdminWorkVisibilityEntryPayload>,
}
/// 后台修改作品可见性请求。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminUpdateWorkVisibilityRequest {
pub source_type: String,
pub profile_id: String,
pub visible: bool,
}
/// 后台修改作品可见性响应。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminUpdateWorkVisibilityResponse {
pub entry: AdminWorkVisibilityEntryPayload,
}
#[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<String>,
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<String>,
pub owner_identity: Option<String>,
pub host_type: Option<String>,
pub schema_table_names: Vec<String>,
pub table_stats: Vec<AdminDatabaseTableStatPayload>,
pub fetch_errors: Vec<String>,
}
// 单表统计允许成功和失败并存,避免某张表失败导致整页概览不可用。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminDatabaseTableStatPayload {
pub table_name: String,
pub row_count: Option<u64>,
pub error_message: Option<String>,
}
// 后台表清单独立用于“表查询”页,避免页面必须先拉完整总览。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminDatabaseTableListResponse {
pub tables: Vec<String>,
pub fetch_errors: Vec<String>,
}
// 后台通用表查询参数,用户输入不进入 SQL,只在 API Server 内存中过滤。
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminDatabaseTableRowsQuery {
pub limit: Option<u32>,
pub search: Option<String>,
pub filters: Option<String>,
}
// 后台通用表查询响应,cells 使用列名映射,raw 保留原始行便于详情排障。
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct AdminDatabaseTableRowsResponse {
pub table_name: String,
pub columns: Vec<String>,
pub rows: Vec<AdminDatabaseTableRowPayload>,
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<Vec<AdminDebugHeaderInput>>,
pub body: Option<String>,
}
// 调试请求头使用显式结构,避免页面直接塞任意对象。
#[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<AdminDebugHeaderInput>,
pub body_text: String,
pub body_json: Option<Value>,
}
// 后台埋点明细查询参数只保留运营筛选需要的只读字段。
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AdminTrackingEventListQuery {
pub event_key: Option<String>,
pub user_id: Option<String>,
pub scope_kind: Option<String>,
pub scope_id: Option<String>,
pub limit: Option<u32>,
}
// 单条埋点原始事件明细,字段与 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<String>,
pub owner_user_id: Option<String>,
pub profile_id: Option<String>,
pub module_key: Option<String>,
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<AdminTrackingEventEntryPayload>,
}