fix(knowledge): verification audit — 3 medium issues

- create_item: wrap item + version INSERT in transaction for atomicity
- update_item handler: validate content length (100KB) before DB hit
- KnowledgeChunk: document missing embedding field, safe per explicit SELECT usage
This commit is contained in:
iven
2026-04-02 19:16:32 +08:00
parent 7e4b787d5c
commit d40c4605b2
3 changed files with 14 additions and 2 deletions

View File

@@ -273,6 +273,12 @@ pub async fn update_item(
) -> SaasResult<Json<serde_json::Value>> {
check_permission(&ctx, "knowledge:write")?;
if let Some(ref content) = req.content {
if content.len() > 100_000 {
return Err(SaasError::InvalidInput("内容不能超过 100KB".into()));
}
}
let updated = service::update_item(&state.db, &id, &ctx.account_id, &req).await?;
// 触发 re-embedding

View File

@@ -296,6 +296,9 @@ pub async fn create_item(
));
}
// 使用事务保证 item + version 原子性
let mut tx = pool.begin().await?;
let item = sqlx::query_as::<_, KnowledgeItem>(
"INSERT INTO knowledge_items \
(id, category_id, title, content, keywords, related_questions, priority, tags, created_by) \
@@ -311,7 +314,7 @@ pub async fn create_item(
.bind(priority)
.bind(tags)
.bind(account_id)
.fetch_one(pool)
.fetch_one(&mut *tx)
.await?;
// 创建初始版本快照
@@ -328,9 +331,10 @@ pub async fn create_item(
.bind(keywords)
.bind(related_questions)
.bind(account_id)
.execute(pool)
.execute(&mut *tx)
.await?;
tx.commit().await?;
Ok(item)
}

View File

@@ -121,6 +121,8 @@ pub struct ItemResponse {
}
// === 知识分块 ===
// 注意DB 表含 embedding vector(1536) 列,但当前所有查询均显式指定列,
// 故 struct 暂不映射该字段。若未来使用 SELECT * 需添加 embedding: Option<pgvector::Vector>。
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
pub struct KnowledgeChunk {