feat: 需求池重构 + 联动引擎 + 开发状态推导

架构:新建 lib/linkage-engine.ts 联动引擎
- deriveReqDevStatus(): 从 devTasks 推导需求开发状态
- canEditRequirement(): 开发中的需求不可编辑
- checkVersionChangeRisk(): 版本变更风险检查
- 所有跨模块推导逻辑集中在此文件

功能改动:
1. 导航改名"需求"→"需求池"
2. 新建需求:所属产品/项目必填,移除产品负责人字段
3. 需求表格新增"开发状态"列:
   未排期/待开发/开发中/已完成(从 devTasks 实时推导)
4. 开发中的需求:编辑按钮禁用
5. 需求设 versionId → 版本详情关联需求天然兼容
   (版本详情通过 filter(r.versionId === versionId) 读取)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Script Generator
2026-06-15 15:09:02 +08:00
parent b30c460571
commit 43d3f76e6a
5 changed files with 76 additions and 28 deletions

View File

@@ -115,19 +115,18 @@ export function RequirementModal({
};
const handleSubmit = () => {
if (!title.trim()) return;
if (!title.trim() || !productId || !projectId) return;
onSubmit({
title: title.trim(),
description: description.trim(),
sourceType,
sourceTarget: sourceTarget || undefined,
productId: productId || undefined,
projectId: projectId || undefined,
productId,
projectId,
versionId: versionId || undefined,
platforms: selectedPlatforms,
typeId: typeId || undefined,
priority,
productOwner: productOwner.trim() || undefined,
parentId: parentId || undefined,
});
};
@@ -241,7 +240,7 @@ export function RequirementModal({
<div className="grid grid-cols-3 gap-3">
<div>
<label className="text-[12px] font-medium text-[var(--ink-soft)] mb-1.5 block">
<span className="text-red-500">*</span>
</label>
<select
value={productId}
@@ -256,7 +255,7 @@ export function RequirementModal({
</div>
<div>
<label className="text-[12px] font-medium text-[var(--ink-soft)] mb-1.5 block">
<span className="text-red-500">*</span>
</label>
<select
value={projectId}
@@ -379,20 +378,6 @@ export function RequirementModal({
</div>
</div>
{/* 9. 产品负责人 */}
<div>
<label className="text-[12px] font-medium text-[var(--ink-soft)] mb-1.5 block">
</label>
<input
type="text"
value={productOwner}
onChange={(e) => setProductOwner(e.target.value)}
placeholder="请输入负责人姓名"
className="h-9 w-full rounded-lg border border-[var(--line)] bg-[var(--bg-card)] px-3 text-[13px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] outline-none focus:border-[var(--accent)]"
/>
</div>
{/* 10. 关联父需求 */}
<div>
<label className="text-[12px] font-medium text-[var(--ink-soft)] mb-1.5 block">