feat: Codex 工作区改动迁移(支付管理/用户余额/创作页等)

将 Codex 在工作区累积的改动整体落到 refactor/rust-backend:
支付管理与用户余额页、各创作 surface、website 等。排除 boosapi.db/config.toml 等敏感文件。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
boos
2026-06-17 22:28:14 +08:00
parent bfd804f719
commit e8508cb056
61 changed files with 6468 additions and 5228 deletions
+4 -4
View File
@@ -113,9 +113,7 @@ impl NotificationService {
let config = self.load_config().await?;
let channels = self.enabled_channels(&config);
if channels.is_empty() {
return Err(AppError::BadRequest(
"请至少配置并启用一个通知通道".into(),
));
return Err(AppError::BadRequest("请至少配置并启用一个通知通道".into()));
}
let notif = Notification {
@@ -466,7 +464,9 @@ fn setting(map: &HashMap<String, String>, key: &str) -> Option<String> {
}
fn setting_bool(map: &HashMap<String, String>, key: &str, default: bool) -> bool {
map.get(key).map(|value| parse_bool(value)).unwrap_or(default)
map.get(key)
.map(|value| parse_bool(value))
.unwrap_or(default)
}
fn parse_bool(value: &str) -> bool {
+5 -6
View File
@@ -1,5 +1,5 @@
use sqlx::SqlitePool;
use parking_lot::RwLock;
use sqlx::SqlitePool;
pub const PROXY_TOKEN_SETTING_KEY: &str = "runtime.auth.proxy_token";
@@ -20,11 +20,10 @@ impl RuntimeAuthSettings {
}
pub async fn load(pool: &SqlitePool, default_proxy_token: String) -> anyhow::Result<Self> {
let stored: Option<String> =
sqlx::query_scalar("SELECT value FROM settings WHERE key = ?")
.bind(PROXY_TOKEN_SETTING_KEY)
.fetch_optional(pool)
.await?;
let stored: Option<String> = sqlx::query_scalar("SELECT value FROM settings WHERE key = ?")
.bind(PROXY_TOKEN_SETTING_KEY)
.fetch_optional(pool)
.await?;
let proxy_token = stored
.as_deref()
.map(str::trim)
+7 -2
View File
@@ -188,7 +188,10 @@ async fn insert_asset(
fn should_project_workspace_asset(status: &str, metadata: &Value) -> bool {
status == "completed"
&& (metadata.pointer("/workspaceAsset/role").and_then(Value::as_str) == Some("output")
&& (metadata
.pointer("/workspaceAsset/role")
.and_then(Value::as_str)
== Some("output")
|| metadata.pointer("/workflowUi/type").and_then(Value::as_str) == Some("output")
|| metadata.get("responseItem").is_some()
|| metadata.get("moneyPrinter").is_some()
@@ -398,7 +401,9 @@ pub async fn project_deleted_asset(state: &AppState, public_id: &str) -> Result<
&source,
&kind,
size_bytes,
file_path.as_deref().is_some_and(|value| !value.trim().is_empty()),
file_path
.as_deref()
.is_some_and(|value| !value.trim().is_empty()),
-1,
)
.await