新增: 初始化 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:
2026-06-12 01:31:05 +08:00
commit 98393b4908
178 changed files with 27859 additions and 0 deletions

View 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 }

View 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![])
}
}

View 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![]
}
}

View 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;

View 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![]
}
}