Files
ftb-project-management/docs/workflow.md
32aaf53b26
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled
docs(workflow): 明确 GitHub 优先推送规则
2026-07-08 20:13:53 +08:00

451 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 工作流程
记录用户的协作偏好和系统化流程,方便后续模型理解项目运作方式。
## 用户协作风格
- **直接修复明确 bug**,不强制走 brainstorming 流程
- **方案确认后立即执行**,不重复讨论
- **不喜欢自动 push**commit 由模型完成,**push 需要用户明说"推/push"**
- **要求高级开发思维**:考虑数据联动、引擎层抽象,而不是分散写 ad-hoc 逻辑
- **重视一致性**:所有 Drawer 阴影、所有时间格式、所有状态计算都要统一
- **省略多余对话**:能直接做的不要问,只在真有歧义时用 AskUserQuestion 给选项
- **Brainstorming 适用于新功能**bug fix 和已批准方案的延续不走 brainstorming
## 实际工时计算流程
所有"实际开始时间"和"实际完成时间"都是 ISO 时间戳:
```
状态变更时机:
- DevTask: todo → in_progress 时记 startDate
testing → submitted 时记 completedAt
- TestCase: pending → running 时记 startedAt
running → passed/failed/blocked 时记 completedAt
- VersionPlan: pending → in_progress 时记 actualStartAt
in_progress → completed 时记 completedAt
计算:
- 实际工时 = (completedAt - startDate) / 3600000精确到 0.5h
- 阶段日历耗时 = min(start) → max(end) 跨度(项目维度,不重复)
- 个人耗时 = 每个任务独立累加(个人维度)
```
## 开发任务延后原因判断
开发任务从“待开发”切换到“开发中”时,只有当前时间已经超过 `expectedEndAt`(预计截止)才要求填写延后原因。超过预计开始时间但仍未超过预计截止时间,不视为延后。
## AI 草案领取与计划流程
开发任务和测试用例由 AI 生成后,版本详情里不再显示独立的“待排期”状态:
1. DevTask / TestCase 没有负责人时显示“待领取”。
2. 点击“领取并填写计划”时同时写入当前用户为负责人,并填写计划起止时间。
3. 已采纳推荐负责人的 AI 草案已经有负责人,不需要领取,但开始开发/测试前仍必须点击“填写计划”补齐计划起止时间。
4. DevTask 开始开发前必须同时具备 `assigneeId``expectedStartAt``expectedEndAt`TestCase 开始测试前必须同时具备 `assigneeId``plannedTestAt``plannedEndAt`
5. 计划起止时间自动按工作日历计算 `estimateHours`。AI 预估仍保留在 `aiEstimateHours`,不代表负责人已确认排期。
## 开发任务提测流程
1. DevTask 从“自测”转为“已提测”前,任务不能处于阻塞中。
2. 如果 `isBlocked=true`,必须先解除阻塞并清空阻塞原因,再允许提测。
3. “已提测”仍然是 DevTask 终态;后续测试通过或失败不回写 DevTask 状态。
## 测试轮次流程
测试用例支持按版本开启多轮测试:
1. 旧测试用例或未写入 `roundNo` 的测试用例默认属于第 1 轮。
2. 点击“开启新一轮测试”时,系统从第 1 轮复制全部测试用例到下一轮,包含 AI 创建和人工创建的用例。
3. 只有最新一轮全部测完(状态为通过、不通过或阻塞)后,才能开启下一轮;第 1 轮未测完不能开启第 2 轮。
4. 新轮次保留用例范围与估时信息关联需求、任务类型、优先级、负责人、引用来源、AI 预估、执行预估。
5. 新轮次清空执行记录:状态回到待测试,不带开始/完成时间、执行人、失败原因、阻塞原因。
6. 测试用例列表、当前轮次进度、无 Bug 通过率按选中的轮次展示。
7. 顶部耗时汇总按当前版本全部轮次累计,实际耗时和人力投入会包含新一轮执行产生的耗时。
8. 测试用例按所属需求分组展示开发提测标签:该需求下所有开发任务都已提测时显示“已提测”,否则显示“待提测”。
## 数据联动检查清单
新加模块或字段时,检查以下点:
- [ ] 是否需要在 `linkage-engine.ts` 加派生函数?
- [ ] 是否需要在 `workspace-engine.ts` 加聚合?
- [ ] 删除版本时是否需要清理这类数据?
- [ ] 工作台 / 版本详情 / 项目详情三处的统计是否同步?
- [ ] 是否需要新增 `app_data` key后端 `data-keys.ts` + 前端 `server-data.ts`
- [ ] 是否需要从旧浏览器数据做一次性迁移?(当前不做本地导入导出)
## Drawer侧边详情规范
所有侧边详情遵循:
- `fixed inset-0 z-50 flex justify-end`
- 背景 `bg-black/40`
- Drawer 容器 `w-full max-w-md h-full bg-[var(--bg)] border-l shadow-2xl flex flex-col`
- 顶部上下文条(可选):`px-5 py-2 bg-[var(--bg-subtle)] text-[11px]`
- 顶栏:`h-14 border-b bg-[var(--bg-card)]`
- 操作按钮按颜色编码blue=进行/转交、emerald=完成、red=删除/失败、orange=关闭/提BUG
## Modal弹窗规范
- 居中 `flex items-center justify-center bg-black/40`
- `rounded-2xl bg-[var(--bg-card)] border shadow-md`
- 提交 BUG 等图片密集型用 `max-w-2xl`,普通表单 `max-w-md``max-w-lg`
## 字段命名规范
- 实际开始:`startDate` (DevTask) / `startedAt` (TestCase) / `actualStartAt` (VersionPlan)
- 实际完成:`completedAt`(统一)
- 派生进度:在 lib 层提供函数,不存储
历史原因导致命名不完全一致DevTask 用 startDate 是因为最早是日期字段),但行为一致。
## 提交信息规范
- 中文 commit message
- 格式:`类型(模块): 描述`
- feat / fix / refactor / docs / test
- 描述列出关键改动点,特别是跨模块影响
- Co-Authored-By 行带版本号
## Git 推送流程
- **push 必须由用户明确要求**:默认只 commit不自动 push。
- **GitHub 是主推送目标**:需要推送时,必须优先确保 GitHub 上的目标分支更新成功,再同步到 Gitea。
- `origin` 配有两个 push URL顺序应保持为 GitHub 在前、Gitea 在后。推送前可用 `git remote get-url --push --all origin` 核对。
- 标准推送命令优先使用显式 refspec`git push origin <local-branch>:<remote-branch>`。这样会按 `origin` 的 push URL 顺序先推 GitHub再推 Gitea并避免当前分支与目标分支不一致时误推。
- 如果 GitHub fetch/push 失败,不要静默改为只推 Gitea也不要把“已推送”视为完成。必须明确告知用户 GitHub 未成功,并等待用户决定是否临时只推 Gitea。
- 推送完成后必须分别核对两边目标分支指向同一个提交:
- `git ls-remote --heads origin <branch>`
- `git ls-remote --heads gitea <branch>`
## 文档维护流程
- **新增/改动核心架构** → 更新 `architecture.md`
- **关键设计决策** → 追加到 `decisions.md`,包含"为什么"
- **新功能/路线图变更** → 更新 `roadmap.md`
- **不影响架构的功能性改动** → 不需要更新文档
## Bug 排查流程
朋友拉新代码出现"显示问题"时,按顺序排查:
1. 后端是否启动:`GET http://localhost:3001/api/v1/config/ai` 应返回 200
2. 数据库是否启动并完成 Prisma 同步:`app_data` 表必须存在
3. 对应 `app_data.key` 是否有值,例如 `products-overview` / `requirements` / `dev-tasks`
4. 前端 store 是否已经调用对应 `fetch*` 方法
5. 类型定义和实际 JSON 数据不一致(缺字段)
6. 列宽溢出导致裁切
7. 派生计算错误filter 条件错)
8. 跨模块联动断了store 的 store.getState() 调用时机)
## 测试 / 验证流程
- 改动后必须 `pnpm type-check` 通过
- 涉及服务端数据持久化:`DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ftb_pm pnpm --filter server exec prisma validate --schema prisma/schema.prisma`
- 涉及 V2.5 后端权限/审计/AppData/一致性:至少运行 `pnpm --filter server test`
- 涉及 UI 改动:`curl http://localhost:3000/<path>` 检查 200
- 不会自动跑 dev server假定它已经运行
## AppData 并发写入流程
- 前端通过 `loadServerData(key)` 读取业务文档时,必须缓存响应里的 `version`
- 前端通过 `saveServerData(key, value)` 保存已读取过的 key 时,必须把最近一次成功读取/保存得到的 `version` 一起提交。
- 后端只在 `key + updatedAt(version)` 匹配时更新;如果其他用户已经先保存,返回 `409 APP_DATA_CONFLICT`,响应包含当前服务端 `currentVersion``currentValue`
- 收到 `ServerDataConflictError` 时,不要自动重试覆盖。当前处理策略是阻止静默覆盖,后续 UI 冲突合并能力再单独补。
## V2.4 领域写入流程
已迁移领域的 store 默认写入顺序:
1. 本地状态先做乐观更新,保持 UI 响应速度。
2. 优先调用 `apps/web/lib/domain-api.ts` 中的领域 API。
3. 领域 API 成功后,用服务端返回行替换本地临时行;若返回 `activities`,直接合并工作活动证据。
4. 领域 API 不可用或旧环境未部署时,才使用 `loadServerData` / `saveServerData` 做 AppData 兼容兜底。
5. 不新增长期双写逻辑AppData fallback 只用于兼容、迁移和回滚,不作为已迁移领域的事实源。
当前领域主写范围:
- Product / Project / Version根数据主写`products-overview` 仅兼容。
- Requirement`productId` 写入,需求池列表走服务端分页、搜索、筛选、排序。
- VersionPlan / DevTask / TestCase / Bug`versionId` 写入,并维护工作活动和小宝 dirty 标记。
- Member / TaskCategory成员身份字段和任务类型字典主写关系表。
- TaskWorklog / OvertimeRecord / WorkActivity证据型数据主写关系表保持追加语义。
仍在 AppData 兼容配置中的内容:
- 部门、角色、密码规则。
- 加班原因。
新增领域 store 时,先写 source contract 测试证明主写不是 `saveServerData('<key>')`,再实现领域 API 和 fallback。
## V2.5 权限、审计与 AppData 退场流程
新增或修改领域 mutation endpoint 时,必须使用统一合同:
1. Controller mutation 使用 `@ProtectedMutation(permission, scope, audit)`,不要只在前端做权限判断。
2. `scope` 必须能从 param/body 中解析 `productId``projectId``versionId`,版本资源优先传 `versionId`
3. Service 写入需要保留 `actorId``resourceScope` 或可推导的产品/项目/版本上下文,便于审计与一致性校验。
4. 成功 mutation 必须写 `audit_events`审计详情中不得暴露密码、token、secret、API key 等敏感字段。
5. 查询审计走 `/admin/audit``GET /api/v1/audit`,需要 `audit:view`
AppData key 退场遵循:
1. 所有业务 key 先在 `AppDataRetirementService` 标注状态和替代路径。
2. `write_frozen` / `read_only_archive` key 的写入返回 `409 APP_DATA_WRITE_FROZEN`;前端捕获 `ServerDataWriteFrozenError` 后提示改用领域 API。
3. 读取仍可用,只用于历史数据核对、兼容导入、归档导出和故障排查。
4. 导出归档使用 `pnpm appdata:archive:export`,归档校验使用 `pnpm appdata:archive:verify -- --archive <file>`
5. 不新增 AppData key 作为主写新业务先设计关系表、Prisma model、领域 API、权限和审计。
一致性检查流程:
1. 本地或部署环境先确保 server 可访问并完成 migration。
2. 运行 `pnpm consistency:v25`,默认检查 `http://localhost:3001/api/v1/consistency`
3. `error` 必须修复后才能继续发布;`warn` 需要记录原因。历史数据缺少审计事件属于 warning不阻断 V2.5。
4. 后台页面 `/admin/consistency``consistency:view` 控制,展示 counts、分区键、孤儿引用和审计覆盖。
跨阶段协调点:
- `xiaobao-risk-snapshots` / `xiaobao-risk-insights` 已进入只读归档V2.6 负责关系表写入、后台任务和重试。
- `xiaobao-warning-views` 已进入只读归档V2.7 负责 per-user read-state API。
- 成员身份写 `users`,但部门、角色、密码规则和加班原因的正式配置 schema 仍属 V2.7 管理治理。
## 与我相关Workspace数据流
```
useProductStore → versions
useRequirementStore → requirements (with versionId)
useDevTaskStore → tasks (with versionId; legacy with requirementId)
useTestCaseStore → testCases (with versionId)
useBugStore → bugs (with versionId)
useVersionPlanStore → plans (with versionId, owner)
useAuthStore → user (filter by current user)
workspace-engine.aggregateWorkItems(...)
WorkItem[] (统一格式)
Workspace 页面(树筛选 + tab 筛选 + 已完成开关)
```
新增模块时,只需在 `aggregateWorkItems` 中添加聚合逻辑,工作台自动展示。
## AI 拆解工作流V3.1
详细 Agent 规范见 `agent-spec.md`。这里是用户视角的工作流:
```
1. 创建版本(不需要单独填原型链接)
2. 在版本详情 → 产品方案 Tab 创建一条 product 计划
3. 完成产品方案计划,提交「成果」(成果链接即原型链接,附成果标题)
4. 从当前项目已采纳需求中关联需求到本版本
5. 点击「AI 拆解开发任务」或「AI 拆解测试用例」按钮(位于产品方案 Tab
6. Agent 从 product 类型的 completed 计划取 resultUrl 作为原型,
抓取原型 + 关联需求 + 版本成员,输出对账报告 + 任务/用例草案
(关联需求优先;原型中明确可拆但没有 REQID 的内容进入“无需求ID”分组
- 生成中状态和完成结果保存在前端 AI 拆解会话中;用户离开版本详情再返回时,未结束的生成继续保持“拆解中”,已完成的生成显示“查看结果”。
- 生成结果只有在用户点击「采纳选中」或「不采纳」后才清空;单纯关闭弹窗或切到其他页面不会丢失结果。
7. 用户审核对账报告
├─ 系统先自动过滤已采纳过的重复 DevTask/TestCase 草案
├─ 报告全 ✅:直接确认写入
├─ 报告有无需求ID分组确认后写入任务/用例,但不创建需求池记录
├─ 报告有 ⚠️/❓:选择性放弃部分草案 / 补充信息后重跑
└─ 报告全 ❓:放弃 AI 拆解,人工创建
8. 确认后DevTask / TestCase 草案写入对应 Tab标记 aiDraft: true并写入 aiEstimateHours
无需求ID草案按 `无需求ID · 需求名称` 分组展示,不额外显示“原型发现”标记
9. 团队成员在 DevTask Tab 看到紫色边的 AI 草案任务
10. 任意成员编辑任务(改标题/描述/负责人/优先级/时间/分类/执行预估),保存后 aiDraft 自动清除
changeStatus / setBlocked 等用户主动操作也会清除)
```
**触发条件**AI 拆解按钮可点):
- 至少有 1 条 type=product 的产品方案计划处于 completed 且 resultUrl 非空
- 至少 1 条需求关联到本版本
**人工创建任务/用例的引用要求**
- 创建 DevTask 时已选「关联需求」自动作为 reference 写入
- 创建表单加「原型批注」字段(手填,逗号或空格分隔,如 `QY0007, QY0023`
- 至少一类引用非空才能保存V3.1 暂未做强校验,靠 UI 引导)
## 高级开发约束:规则先归位
涉及以下任意类型的改动时,先判断规则应该放在哪一层,不允许直接在页面组件里散写临时判断:
- 跨模块联动:例如 Requirement、VersionPlan、DevTask、TestCase、Bug 互相派生状态。
- 状态流转:例如 `pending -> in_progress -> completed``todo -> testing -> submitted`
- 完成条件:例如子任务是否完成、是否提交成果、是否允许点击完成。
- 候选数据来源:例如关联需求只能来自当前项目已采纳需求,不能从全量需求池随手取。
- AI 写入契约:例如 AI 输出任务类型、引用来源、草案标记。
- AI 无需求ID分组原型中明确可拆但没有匹配关联需求的内容只写入 DevTask/TestCase 的 `requirementName`,不进入需求池或版本关联需求列表。
默认落点:
- 可派生数据进 `*-engine.ts` 或纯函数 helper。
- 有状态流转的实体要有状态机或 workflow helper。
- 多个组件共用的候选筛选规则进 selector/helper。
- AI 输入输出字段先更新 `agent-spec.md` 和 shared type再改 prompt/schema。
AI 估时约束:
- `aiEstimateHours` 是 AI 建议工时,只能由 AI 拆解写入。
- `estimateHours` 是执行人预估,只能由人工创建/编辑或负责人确认排期时写入。
- 统计进度优先取 `estimateHours`,没有时取 `aiEstimateHours`,避免 AI 草案在未确认前失去统计权重。
版本模块新增规则:
- `version-plan-workflow.ts` 是调研/产品方案/UI 设计完成条件的唯一入口。
- `requirement-selector.ts` 是版本内关联需求候选的唯一入口。
- `TaskCategory.name` 是 AI 草案的可复用任务类型锚点;可复用开发类型可自动入库,测试用例未知类型回退到已有测试分类。`TaskCategory.code` 仅作为可选兼容映射,`id` 只作为存储主键。
- DevTask 新数据必须有 `versionId``requirementId` 作为正式需求语义标签可选。版本级聚合走 `versionId`,需求级进度只统计带 `requirementId` 的任务。
- 产品方案和 UI 设计的引用需求不再用 checkbox 直接标记完成,必须通过 `requirementCoverage[]` 记录 `not_started / partial / completed`、本次已完成内容和剩余内容;只有 `completed` 计入成果提交门禁。
- 产品/UI 计划右侧展示计划日志,需求进度更新和 AI 拆解触发/完成/失败都写入 `VersionPlan.logs[]`,页面只消费日志数据,不临时拼历史。
- 调研/产品方案/UI 设计的计划级 `actualStartAt` 只表示计划容器已开始,不直接作为具体任务日报耗时。具体调研方向或引用需求需要先点击「开始任务」,写入当前行的 `currentWorkStartedAt`;提交「记录」时日志和 `work-activities` 保留 `workStartedAt`,日报耗时按 `workStartedAt -> 记录提交时间` 计算,提交后清空当前行的开始时间。完全完成可直接提交结束本次耗时,部分完成才需要填写本次已完成内容和剩余未完成内容。
## Production Release Workflow (2026-07-06)
Production releases use GitHub Actions as the default path. The deployment side should not manually rebuild frontend assets after every change; it keeps `.env.production` and Docker volumes, while Actions builds immutable images and updates the running containers.
Standard flow:
1. Merge or push to `master`.
2. GitHub Actions builds `web` and `server` images with `APP_VERSION=<commit-sha>`.
3. Actions pushes the images to GHCR.
4. Actions SSHes into the server, updates `.env.production` image tags, pulls the images, runs `pnpm --filter server db:deploy`, and restarts Compose.
5. Actions verifies `/api/v1/health/version` equals the commit SHA.
If a user reports "latest code pulled but UI is still old", first compare the running version endpoint with the expected commit. A mismatch means deployment did not update the running container. A match means the code is deployed and the remaining issue is likely browser cache, data, or business logic.
## Work Activity Daily Report Flow (2026-06-26)
The daily report flow uses mixed evidence:
1. Automatic evidence is written when a user performs a successful domain action:
- VersionPlan created, started, or completed.
- DevTask created, started, moved to self-test, submitted to test, blocked, or unblocked.
- TestCase created, started, passed, failed, or blocked.
- Bug created, moved to fixing, fixed, closed, or transferred.
2. Manual progress notes are used for multi-day work that does not change status today.
- DevTask「今日进展」必须填写 `nextStartAt`,默认值为第二天 09:30。
-`nextStartAt` 的进展记录按「上一条记录的 `nextStartAt` → 本次记录时间」计算当日耗时;如果任务是当天开始,才回退到当天实际开始时间。
3. `/workspace` shows only the current logged-in user's report.
4. Project-owner and management views will reuse the same `work-activities` data later, but are not part of the personal workspace panel.
Implementation convention:
- Activity wording and category mapping belong in `apps/web/lib/work-activity-factory.ts`.
- Daily report grouping belongs in `apps/web/lib/workspace-daily-report.ts`.
- Page components should consume report output, not rebuild report rules.
## 小宝预警工作流
小宝预警位于主导航“工作区 / 小宝预警”,展示在“与我相关”上方。可见范围由角色权限控制:
- `xiaobao.warning:manage`:查看所有未结束版本的预警。
- `xiaobao.warning:view`:仅查看当前用户在 `version.members` 中的未结束版本。
V2.6/V3.2 后小宝当前 summary 由服务端后台刷新:领域写入标记 `xiaobao_risk_summaries.dirty=true` 并排入 `xiaobao.summary.refresh`worker 从版本下的计划、开发任务、测试用例、Bug、日报和工作活动重新计算风险。页面仍可用前端 `buildXiaobaoWorkItems` 做兼容聚合和快照保存,但默认优先读取 V2.2 summary。
AI 解读不由人工按钮触发。服务端 summary 刷新后按 policy 排入 `xiaobao.ai.interpret``at_risk``likely_delayed``blocked` 自动触发;`attention` 当前服务端只在临近发版且仍有未完成工作时触发,页面完整趋势策略仍保留作为兼容。缓存命中时复用解读;同版本最近 6 小时内已有解读时进入 cooldown不重复请求风险等级升级时可绕过缓存保存时间使用服务端写入时间不信任模型返回的 `generatedAt` 作为缓存新鲜度。V2.2 小宝快读会带出当前版本最新 generated 关系表解读,前端优先展示这份解读,再兼容旧 `xiaobao-risk-insights` AppData 缓存。
静默风险包括长期无更新、无日报、无活动、进行中事项无人处理等信号。日报和工作活动是风险解释的重要证据,必须进入 AI 解读输入。
## V2.7 协作治理工作流
通知统一进入 `notifications` 关系表,事件类型固定为:
- `assignment`:负责人或处理人被分配工作。
- `mention`:评论中 `@成员名` 或显式选择成员。
- `risk_alert`:小宝预警保存高风险快照后提醒管理者。
- `overdue_item`:逾期事项提醒。
评论统一使用 `CommentPanel`,支持 DevTask、TestCase、Bug、Requirement 和 VersionPlan。创建/删除评论必须写 audit提及成员必须生成 mention 通知。
项目成员治理走 `/projects/:projectId/members` 服务端接口。角色为 Owner/Admin/Member/ViewerOwner/Admin 可管理成员;服务端禁止移除或降级最后一个 Owner。版本成员可见性继续兼容旧 `version.members` 展示,但治理来源应逐步收敛到 ProjectMember。
管理驾驶舱 `/admin/management` 只查关系表和小宝 summary不读取 AppData并通过 RBAC adapter 校验 `management:view`。治理设置 `/admin/governance` 集中维护任务类型与需求字典;使用中的字典不可硬删,字典变更必须写 audit并通过 RBAC adapter 校验 `governance:manage`
## Business Analysis Agent 工作流(规划)
Business Analysis Agent 用于 AI 助手业务数据对话,以及产品/项目/版本详情页的上下文分析入口。它只读关系表和 summary不写业务数据。
标准流程:
1. 用户在 `/wenfan-xiaobao` 或详情页输入问题。
2. 前端提交问题和上下文:`surface``productId``projectId``versionId`
3. 后端 Analysis Planner 识别用户意图。
4. Semantic Layer 将自然语言映射成系统语义、指标、维度、分析类型和时间意图。
5. Permission Scope Resolver 根据当前用户权限和页面上下文收窄数据范围。
6. Analysis Strategy 生成分析计划:
- Template Strategy 优先命中固定高频模板。
- Rule Composition Strategy 用确定性规则组合已知指标、维度和时间口径。
- AI Planning Strategy 只生成计划建议,不直接执行。
7. Analysis Plan Processor 校验权限、指标、维度、聚合、时间范围、Top N 和筛选条件,并规范化为统一 `AnalysisPlan`
8. Metric Engine 执行关系表查询和聚合,返回 `MetricResult`
9. ChartSpec Builder、Insight Engine、Report Builder、Follow-up Builder 并行消费 `MetricResult`
10. 前端展示 Insight Card、ECharts 图表、固定结构报告、可点击 Evidence 和只读 Follow-up。
时间口径:
- 用户明确说本月、季度、年份、最近 N 天时,按用户指定。
- 当前状态或风险问题不默认套近 30 天,使用实时状态、未完成事项、小宝 summary、阻塞、Bug、测试完成率和发版日期。
- 趋势、吞吐、效率、投入和变化类问题,用户未指定时间时默认近 30 天。
- 对比类问题未指定基准时,用近 30 天对比前 30 天。
- 生命周期类问题按对象生命周期统计。
- 每次回答必须显示统计范围、数据截止时间、权限范围和时间口径类型。
无数据时返回 No Data 结果,不生成虚假解释。低语义置信时先说明系统默认解释,必要时给用户可选追问。
视觉工作流:
- 结果先显示一句 Insight Card再显示图表和报告。
- 图表使用平台 Unified ChartSpec通过前端 ECharts Renderer 渲染。
- 图表遵循 AI Analysis Design SystemApple Vision 风格、大留白、大圆角、轻阴影、半透明材质、数字优先、折线面积渐变、横向圆角柱状、少坐标、少颜色、无大屏炫光。
## 日期选择与计划时间
- 调研、产品方案、UI 设计、开发任务、测试用例、Bug 创建时使用统一工作日日期时间选择器。
- 日期选择器接入中国节假日日历。当前内置 2026 年国务院办公厅放假调休安排;其他年份先按周末/工作日兜底。
- 非工作日只提示,不阻止保存;调休工作日按工作日提示。
- 测试用例计划测试时间字段为 `plannedTestAt` / `plannedEndAt`Bug 计划修复时间字段为 `plannedFixAt`
- 测试轮次复制用例时保留计划测试起止时间、AI 预估和执行预估,清空实际执行记录。
## 工时统计口径
- 正常任务耗时使用 `calcWorkHours` / `calcActualElapsedHours`,按中国工作日历和 9:00-12:00、13:00-18:00 工作时段计算。
- 法定节假日和周末不计入正常任务耗时;调休上班日计入正常任务耗时。
- AI 预估工时和手填执行预估工时本身是小时数,不再按日期过滤;只有从计划起止时间自动推导的执行预估会按工作日历计算。
- 加班记录使用 `overtime.calcDuration`,不受节假日过滤,但按项目管理口径计算:每个自然日默认最多 8h跨天中间日期按 8h结束晚于 18:00 的当天额外计入超出时长,避免把夜间空档当作打卡工时。
- 新建加班记录也使用工作日历日期选择器;节假日和周末可选,只提示不阻止。
## 生产部署流程
生产部署以 `docs/deployment.md` 为准,标准顺序如下:
本地服务器/局域网部署:
1. 复制 `.env.local-server.example``.env.local-server`,按需把 `LOCAL_ACCESS_HOST``NEXTAUTH_URL` 改为本机局域网 IP。
2. 运行 `pnpm deploy:verify`
3. 运行 `pnpm deploy:local:build` 构建镜像。
4. 运行 `pnpm deploy:local:up` 启动服务,默认访问 `http://localhost:8080`
5. 首次部署或升级后运行 `docker compose --env-file .env.local-server -f docker-compose.local.yml exec server pnpm --filter server db:deploy`
6.`curl http://localhost:8080/api/v1/config/ai` 验证 Nginx 到后端链路。
云服务器部署:
1. 复制 `.env.production.example``.env.production`,替换密码、域名、`NEXTAUTH_SECRET`、AI key 等真实值。
2. 运行 `pnpm deploy:verify`,确认生产 Docker、Compose、Nginx、env 示例和文档齐全。
3. 运行 `docker compose --env-file .env.production -f docker-compose.prod.yml build` 构建镜像。
4. 运行 `docker compose --env-file .env.production -f docker-compose.prod.yml up -d` 启动服务。
5. 首次部署或升级后运行 `docker compose --env-file .env.production -f docker-compose.prod.yml exec server pnpm --filter server db:deploy`
6.`curl http://localhost/api/v1/config/ai` 验证 Nginx 到后端链路。
7.`docker compose --env-file .env.production -f docker-compose.prod.yml ps``logs -f server/web/nginx` 排查健康状态。
生产环境不提交 `.env.production`。HTTPS 默认由外层负载均衡、CDN、宿主机证书工具或外层 Nginx 终止Compose 内置 Nginx 只承担同域 HTTP 反代。