新增: 知识图谱Phase2事件流(父⑥) — project_events统一事件流+埋点+timeline
父⑥ Phase 2(对标设计 §2.4): - V30 迁移:project_events 追加型审计表(id/project_id/event_type/entity_type/entity_id/from_state/to_state/context_json/source/conversation_id/created_at)+ 双索引(project,time / entity) - ProjectEventRecord + ProjectEventRepo(insert 追加型/get_by_project/get_by_entity/list_recent) - 事件埋点(best-effort,hook/after,失败 warn 不阻断主操作): - task.rs emit_event 辅助 + create_task/advance_task/move_task_queue 埋点 - idea.rs promote_idea 埋点(idea_promoted,project_id=新项目) - project.rs create/delete 埋点 - 注:idea_created 暂不埋点(idea 无 project_id,待 Inbox 项目落地,NOT NULL+FK 约束) - get_project_timeline IPC(events 模块)+ lib.rs 注册 + AI 工具(基线 +N) - source 语义:IPC 标 human,AI 工具路径标 ai 注:workflow 脚本中文变量名 const 致验证 agent 未跑,主控独立 cargo check EXIT 0 + grep 落地齐全核验。
This commit is contained in:
@@ -9,7 +9,7 @@ use df_ai::provider::LlmProvider;
|
||||
use df_types::types::{new_id, Priority};
|
||||
use df_ideas::capture::Idea;
|
||||
use df_storage::crud::{is_unique_constraint_err, IdeaQuery};
|
||||
use df_storage::models::{IdeaEvaluationRecord, IdeaRecord, ProjectRecord};
|
||||
use df_storage::models::{IdeaEvaluationRecord, IdeaRecord, ProjectEventRecord, ProjectRecord};
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
@@ -104,6 +104,12 @@ pub async fn create_idea(
|
||||
.insert(record.clone())
|
||||
.await
|
||||
.map_err(err_str)?;
|
||||
// 知识图谱 Phase 2(对标设计 §2.4):idea_created 事件**暂不埋点**。
|
||||
// 原因:project_events.project_id 是 NOT NULL + FK(PRAGMA foreign_keys=ON),
|
||||
// 而 idea 无 project_id(立项前不属于任何项目)。设计 §2.5 计划用系统初始化创建的
|
||||
// Inbox 项目作为无主 idea 的归属,但 Inbox 项目尚未实现(独立任务)。
|
||||
// 写 NULL 会违反 NOT NULL,写不存在的 project_id 会违反 FK——两者都会让 best-effort
|
||||
// 退化成「写失败 warn」,无实际价值且噪音。Inbox 项目落地后此处补 idea_created 埋点。
|
||||
Ok(record)
|
||||
}
|
||||
|
||||
@@ -201,6 +207,31 @@ pub async fn promote_idea(
|
||||
return Err(format!("灵感立项回写失败(已回滚项目创建): {}", e));
|
||||
}
|
||||
|
||||
// 知识图谱 Phase 2(对标设计 §2.4 hook/after):idea_promoted 事件。best-effort 不阻断。
|
||||
// 灵感此时已立项为新项目(project_id 存在,FK 满足),事件挂在 project_id 下,
|
||||
// entity 指向 idea,from_state=draft→to_state=promoted。
|
||||
let event = ProjectEventRecord {
|
||||
id: new_id(),
|
||||
project_id: project_id.clone(),
|
||||
event_type: "idea_promoted".to_string(),
|
||||
entity_type: Some("idea".to_string()),
|
||||
entity_id: Some(id.clone()),
|
||||
from_state: Some("draft".to_string()),
|
||||
to_state: Some("promoted".to_string()),
|
||||
context_json: None,
|
||||
source: Some("human".to_string()),
|
||||
conversation_id: None,
|
||||
created_at: now_millis(),
|
||||
};
|
||||
if let Err(e) = state.project_events.insert(event).await {
|
||||
tracing::warn!(
|
||||
idea_id = %id,
|
||||
project_id = %project_id,
|
||||
error = %e,
|
||||
"[事件流] idea_promoted 埋点写入失败(不阻断立项)"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(df_ideas::promotion::PromotionResult {
|
||||
idea_id: id,
|
||||
project_id: project_id,
|
||||
|
||||
Reference in New Issue
Block a user