新增: 初始化 DevFlow 项目仓库
Tauri 2 + Vue 3 + Vite 6 桌面应用,Rust workspace 含 13 个 crate (df-ai / df-storage / df-workflow / df-core / df-execute 等)。 核心能力:AI 聊天 agentic 循环(工具调用+人工审批)、工作流引擎、 任务/想法/项目/阶段管理、可追溯性,及配套前端组件。
This commit is contained in:
11
crates/df-traceability/Cargo.toml
Normal file
11
crates/df-traceability/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "df-traceability"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
df-core = { path = "../df-core" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
130
crates/df-traceability/src/annotation.rs
Normal file
130
crates/df-traceability/src/annotation.rs
Normal file
@@ -0,0 +1,130 @@
|
||||
//! 标注系统:FIXME/TODO/QUESTION 等标记,批量收集后交给 AI 处理
|
||||
|
||||
use df_core::types::ProjectId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// 标注标记类型
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AnnotationMarker {
|
||||
/// 需要修复
|
||||
Fixme,
|
||||
/// 待办事项
|
||||
Todo,
|
||||
/// 疑问待确认
|
||||
Question,
|
||||
/// 风险标记
|
||||
Risk,
|
||||
/// 决策标记
|
||||
Decision,
|
||||
/// 优化建议
|
||||
Optimize,
|
||||
}
|
||||
|
||||
/// 标注状态
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AnnotationStatus {
|
||||
/// 未处理
|
||||
Open,
|
||||
/// AI 处理中
|
||||
AiProcessing,
|
||||
/// 已解决
|
||||
Resolved,
|
||||
/// 不处理
|
||||
WontFix,
|
||||
}
|
||||
|
||||
/// 标注可附加的实体类型
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EntityType {
|
||||
Requirement,
|
||||
Feature,
|
||||
Code,
|
||||
TestCase,
|
||||
TestReport,
|
||||
DesignDoc,
|
||||
}
|
||||
|
||||
/// 标注
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Annotation {
|
||||
pub id: String,
|
||||
pub project_id: ProjectId,
|
||||
/// 附加的实体类型
|
||||
pub entity_type: EntityType,
|
||||
/// 附加的实体 ID
|
||||
pub entity_id: String,
|
||||
/// 标记类型
|
||||
pub marker: AnnotationMarker,
|
||||
/// 标注内容
|
||||
pub content: String,
|
||||
/// 位置(文件路径+行号 / 文档段落)
|
||||
pub location: Option<String>,
|
||||
/// 状态
|
||||
pub status: AnnotationStatus,
|
||||
/// 处理者
|
||||
pub resolved_by: Option<String>,
|
||||
/// 处理结果
|
||||
pub resolution: Option<String>,
|
||||
pub created_at: i64,
|
||||
pub resolved_at: Option<i64>,
|
||||
}
|
||||
|
||||
impl Annotation {
|
||||
pub fn new(
|
||||
project_id: ProjectId,
|
||||
entity_type: EntityType,
|
||||
entity_id: String,
|
||||
marker: AnnotationMarker,
|
||||
content: String,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: df_core::types::new_id(),
|
||||
project_id,
|
||||
entity_type,
|
||||
entity_id,
|
||||
marker,
|
||||
content,
|
||||
location: None,
|
||||
status: AnnotationStatus::Open,
|
||||
resolved_by: None,
|
||||
resolution: None,
|
||||
created_at: chrono::Utc::now().timestamp(),
|
||||
resolved_at: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 标注批量处理器
|
||||
pub struct AnnotationBatchProcessor;
|
||||
|
||||
impl AnnotationBatchProcessor {
|
||||
/// 收集项目中所有未处理的标注
|
||||
pub fn collect_open_annotations(_project_id: &ProjectId) -> Vec<Annotation> {
|
||||
// TODO: 从 SQLite 查询所有 status = Open 的标注
|
||||
vec![]
|
||||
}
|
||||
|
||||
/// 按类型分组
|
||||
pub fn group_by_marker(annotations: &[Annotation]) -> std::collections::HashMap<AnnotationMarker, Vec<&Annotation>> {
|
||||
let mut groups: std::collections::HashMap<AnnotationMarker, Vec<&Annotation>> = std::collections::HashMap::new();
|
||||
for ann in annotations {
|
||||
groups.entry(ann.marker.clone()).or_default().push(ann);
|
||||
}
|
||||
groups
|
||||
}
|
||||
|
||||
/// 将分组后的标注交给 AI 批量处理
|
||||
///
|
||||
/// AI 会逐条处理每个标注,更新内容和状态
|
||||
pub async fn batch_process(_annotations: &[Annotation]) -> anyhow::Result<Vec<Annotation>> {
|
||||
// TODO: 调用 df-ai 编排器,构建批量处理 prompt
|
||||
// 1. 按类型分组
|
||||
// 2. 每组构建一个 AI 请求
|
||||
// 3. AI 返回处理结果
|
||||
// 4. 更新标注状态和 resolution
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
95
crates/df-traceability/src/decision.rs
Normal file
95
crates/df-traceability/src/decision.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
//! 决策留痕:所有关键决策的记录、检索和审计
|
||||
|
||||
use df_core::types::{DecisionId, ProjectId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// 决策记录
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Decision {
|
||||
pub id: DecisionId,
|
||||
pub project_id: ProjectId,
|
||||
/// 决策背景
|
||||
pub context: String,
|
||||
/// 需要决定的问题
|
||||
pub question: String,
|
||||
/// 考虑过的方案
|
||||
pub alternatives: Vec<String>,
|
||||
/// 最终决定
|
||||
pub decision: String,
|
||||
/// 决策原因
|
||||
pub reason: String,
|
||||
/// 决策者
|
||||
pub decided_by: DecidedBy,
|
||||
/// 关联实体类型
|
||||
pub entity_type: Option<String>,
|
||||
/// 关联实体 ID
|
||||
pub entity_id: Option<String>,
|
||||
/// 影响范围
|
||||
pub impact: Option<String>,
|
||||
/// 所处阶段
|
||||
pub stage: Option<String>,
|
||||
pub created_at: i64,
|
||||
}
|
||||
|
||||
/// 决策者
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DecidedBy {
|
||||
/// AI 自动决策
|
||||
Ai,
|
||||
/// 人工决策
|
||||
Human,
|
||||
/// AI 建议后人工确认
|
||||
AiSuggested,
|
||||
}
|
||||
|
||||
/// 决策日志
|
||||
pub struct DecisionJournal;
|
||||
|
||||
impl DecisionJournal {
|
||||
/// 记录新决策
|
||||
pub fn record(
|
||||
project_id: ProjectId,
|
||||
context: String,
|
||||
question: String,
|
||||
alternatives: Vec<String>,
|
||||
decision: String,
|
||||
reason: String,
|
||||
decided_by: DecidedBy,
|
||||
) -> Decision {
|
||||
Decision {
|
||||
id: df_core::types::new_id(),
|
||||
project_id,
|
||||
context,
|
||||
question,
|
||||
alternatives,
|
||||
decision,
|
||||
reason,
|
||||
decided_by,
|
||||
entity_type: None,
|
||||
entity_id: None,
|
||||
impact: None,
|
||||
stage: None,
|
||||
created_at: chrono::Utc::now().timestamp(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 查询项目的决策历史
|
||||
pub fn query_by_project(_project_id: &ProjectId) -> Vec<Decision> {
|
||||
// TODO: SQLite 查询
|
||||
vec![]
|
||||
}
|
||||
|
||||
/// 按阶段筛选
|
||||
pub fn filter_by_stage<'a>(decisions: &'a [Decision], stage: &str) -> Vec<&'a Decision> {
|
||||
decisions.iter().filter(|d| d.stage.as_deref() == Some(stage)).collect()
|
||||
}
|
||||
|
||||
/// 生成决策时间线
|
||||
///
|
||||
/// 按时间顺序展示项目的所有决策,用于复盘和审计
|
||||
pub fn timeline(_project_id: &ProjectId) -> Vec<Decision> {
|
||||
// TODO: 查询并按 created_at 排序
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
9
crates/df-traceability/src/lib.rs
Normal file
9
crates/df-traceability/src/lib.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
//! 可追溯性引擎:标注系统、决策留痕、需求-测试映射
|
||||
|
||||
pub mod annotation;
|
||||
pub mod decision;
|
||||
pub mod traceability;
|
||||
|
||||
pub use annotation::{Annotation, AnnotationMarker, AnnotationStatus};
|
||||
pub use decision::{Decision, DecisionJournal};
|
||||
pub use traceability::TraceabilityMatrix;
|
||||
78
crates/df-traceability/src/traceability.rs
Normal file
78
crates/df-traceability/src/traceability.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
//! 需求-功能-测试可追溯矩阵
|
||||
//!
|
||||
//! 建立需求 → 功能 → 测试用例 → 测试报告 的双向追溯关系
|
||||
|
||||
use df_core::types::ProjectId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// 追溯关系
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TraceLink {
|
||||
/// 上游实体类型 (Requirement / Feature)
|
||||
pub source_type: String,
|
||||
pub source_id: String,
|
||||
/// 下游实体类型 (Feature / TestCase / TestRun)
|
||||
pub target_type: String,
|
||||
pub target_id: String,
|
||||
}
|
||||
|
||||
/// 覆盖率统计
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CoverageReport {
|
||||
/// 功能总数
|
||||
pub total_features: usize,
|
||||
/// 已选中功能数
|
||||
pub selected_features: usize,
|
||||
/// 有测试用例的功能数
|
||||
pub features_with_tests: usize,
|
||||
/// 测试覆盖率百分比
|
||||
pub coverage_percent: f32,
|
||||
/// 测试通过率
|
||||
pub pass_rate: f32,
|
||||
}
|
||||
|
||||
/// 可追溯矩阵
|
||||
pub struct TraceabilityMatrix;
|
||||
|
||||
impl TraceabilityMatrix {
|
||||
/// 创建追溯关系
|
||||
pub fn link(
|
||||
source_type: &str,
|
||||
source_id: &str,
|
||||
target_type: &str,
|
||||
target_id: &str,
|
||||
) -> TraceLink {
|
||||
TraceLink {
|
||||
source_type: source_type.to_string(),
|
||||
source_id: source_id.to_string(),
|
||||
target_type: target_type.to_string(),
|
||||
target_id: target_id.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 查询功能的完整追溯链
|
||||
///
|
||||
/// Feature → [TestCases] → [TestRuns] → [TestReports]
|
||||
pub fn trace_feature(_feature_id: &str) -> Vec<TraceLink> {
|
||||
// TODO: SQLite 查询完整链路
|
||||
vec![]
|
||||
}
|
||||
|
||||
/// 生成覆盖率报告
|
||||
pub fn coverage_report(_project_id: &ProjectId) -> CoverageReport {
|
||||
// TODO: 统计功能-测试用例覆盖情况
|
||||
CoverageReport {
|
||||
total_features: 0,
|
||||
selected_features: 0,
|
||||
features_with_tests: 0,
|
||||
coverage_percent: 0.0,
|
||||
pass_rate: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// 查找未覆盖的功能(有功能但无测试用例)
|
||||
pub fn uncovered_features(_project_id: &ProjectId) -> Vec<String> {
|
||||
// TODO: 找出没有关联测试用例的功能
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user