fix: tolerate stale workspace asset owners

This commit is contained in:
boos
2026-06-29 11:34:24 +08:00
parent 7e1bfdd7fe
commit 6863ccd16c
+30 -1
View File
@@ -122,6 +122,32 @@ async fn write_asset_file(
Ok(path) Ok(path)
} }
async fn normalize_asset_user_id(
state: &AppState,
user_id: Option<i64>,
source: &str,
) -> Result<Option<i64>, AppError> {
let Some(user_id) = user_id else {
return Ok(None);
};
let exists = sqlx::query_scalar::<_, i64>("SELECT 1 FROM users WHERE id = ? LIMIT 1")
.bind(user_id)
.fetch_optional(&*state.db)
.await?
.is_some();
if exists {
Ok(Some(user_id))
} else {
tracing::warn!(
user_id,
source,
"workspace asset owner no longer exists; storing asset without user owner"
);
Ok(None)
}
}
async fn insert_asset( async fn insert_asset(
state: &AppState, state: &AppState,
input: &WorkspaceAssetInput, input: &WorkspaceAssetInput,
@@ -236,8 +262,9 @@ async fn upsert_workspace_asset_daily(
pub async fn record_remote_asset( pub async fn record_remote_asset(
state: &AppState, state: &AppState,
input: WorkspaceAssetInput, mut input: WorkspaceAssetInput,
) -> Result<StoredWorkspaceAsset, AppError> { ) -> Result<StoredWorkspaceAsset, AppError> {
input.user_id = normalize_asset_user_id(state, input.user_id, &input.source).await?;
let public_id = format!("wa_{}", Uuid::new_v4().simple()); let public_id = format!("wa_{}", Uuid::new_v4().simple());
let Some(url) = input.remote_url.as_deref() else { let Some(url) = input.remote_url.as_deref() else {
return insert_asset( return insert_asset(
@@ -315,6 +342,7 @@ pub async fn record_base64_asset(
mut input: WorkspaceAssetInput, mut input: WorkspaceAssetInput,
value: &str, value: &str,
) -> Result<StoredWorkspaceAsset, AppError> { ) -> Result<StoredWorkspaceAsset, AppError> {
input.user_id = normalize_asset_user_id(state, input.user_id, &input.source).await?;
let public_id = format!("wa_{}", Uuid::new_v4().simple()); let public_id = format!("wa_{}", Uuid::new_v4().simple());
let trimmed = value.trim(); let trimmed = value.trim();
let (mime_type, encoded) = if let Some(rest) = trimmed.strip_prefix("data:") { let (mime_type, encoded) = if let Some(rest) = trimmed.strip_prefix("data:") {
@@ -351,6 +379,7 @@ pub async fn record_bytes_asset(
bytes: &[u8], bytes: &[u8],
mime_type: &str, mime_type: &str,
) -> Result<StoredWorkspaceAsset, AppError> { ) -> Result<StoredWorkspaceAsset, AppError> {
input.user_id = normalize_asset_user_id(state, input.user_id, &input.source).await?;
let public_id = format!("wa_{}", Uuid::new_v4().simple()); let public_id = format!("wa_{}", Uuid::new_v4().simple());
input.remote_url = None; input.remote_url = None;
let ext = extension_for_mime(mime_type); let ext = extension_for_mime(mime_type);