From efdfb331bbb834aae90cb8dc7de0b03dd2181d8a Mon Sep 17 00:00:00 2001 From: Citrons <909229731@qq.com> Date: Wed, 12 Aug 2026 18:18:55 +0800 Subject: [PATCH] =?UTF-8?q?docs(GOV-001):=20=E5=BB=BA=E7=AB=8B=E5=B7=A5?= =?UTF-8?q?=E7=A8=8B=E6=B2=BB=E7=90=86=E4=B8=8E=E8=BF=BD=E6=BA=AF=E8=A7=84?= =?UTF-8?q?=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 12 ++ .githooks/commit-msg | 22 ++++ .gitignore | 26 ++++ AGENTS.md | 63 ++++++++++ CHANGELOG.md | 7 ++ README.md | 31 +++++ VERSION | 1 + deploy/.gitkeep | 1 + docs/.gitkeep | 1 + .../ADR-0001-monorepo-independent-deploy.md | 22 ++++ docs/adr/ADR-0002-gitnexus-double-gate.md | 16 +++ docs/architecture/system-architecture.md | 41 +++++++ .../FEAT-MO-001-market-overview/design.md | 5 + .../implementation-plan.md | 8 ++ .../FEAT-MO-001-market-overview/manifest.yaml | 11 ++ .../requirements.md | 5 + .../FEAT-MO-001-market-overview/test-plan.md | 8 ++ .../GOV-001-engineering-governance/design.md | 11 ++ .../gitnexus/after.md | 8 ++ .../gitnexus/before.md | 8 ++ .../gitnexus/comparison.md | 10 ++ .../gitnexus/detected-changes.md | 21 ++++ .../gitnexus/impact-plan.md | 18 +++ .../implementation-plan.md | 9 ++ .../manifest.yaml | 17 +++ .../qa/test-results.md | 27 ++++ .../qa/visual-qa.md | 3 + .../release-notes.md | 3 + .../requirements.md | 14 +++ .../rollback.md | 3 + .../test-plan.md | 8 ++ docs/gitnexus/architecture-summary.md | 11 ++ docs/gitnexus/history/v0.0.0-governance.md | 11 ++ docs/gitnexus/repository-baseline.md | 8 ++ docs/governance/code-development-standards.md | 115 ++++++++++++++++++ docs/governance/development-workflow.md | 98 +++++++++++++++ docs/governance/documentation-traceability.md | 43 +++++++ docs/governance/version-control-and-gitea.md | 40 ++++++ docs/index.md | 27 ++++ package.json | 11 ++ server/.gitkeep | 1 + tools/governance/feature-record.mjs | 51 ++++++++ tools/governance/feature-record.test.mjs | 45 +++++++ tools/governance/finish.mjs | 65 ++++++++++ tools/governance/start.mjs | 63 ++++++++++ web/.gitkeep | 1 + 46 files changed, 1030 insertions(+) create mode 100644 .editorconfig create mode 100755 .githooks/commit-msg create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 VERSION create mode 100644 deploy/.gitkeep create mode 100644 docs/.gitkeep create mode 100644 docs/adr/ADR-0001-monorepo-independent-deploy.md create mode 100644 docs/adr/ADR-0002-gitnexus-double-gate.md create mode 100644 docs/architecture/system-architecture.md create mode 100644 docs/features/FEAT-MO-001-market-overview/design.md create mode 100644 docs/features/FEAT-MO-001-market-overview/implementation-plan.md create mode 100644 docs/features/FEAT-MO-001-market-overview/manifest.yaml create mode 100644 docs/features/FEAT-MO-001-market-overview/requirements.md create mode 100644 docs/features/FEAT-MO-001-market-overview/test-plan.md create mode 100644 docs/features/GOV-001-engineering-governance/design.md create mode 100644 docs/features/GOV-001-engineering-governance/gitnexus/after.md create mode 100644 docs/features/GOV-001-engineering-governance/gitnexus/before.md create mode 100644 docs/features/GOV-001-engineering-governance/gitnexus/comparison.md create mode 100644 docs/features/GOV-001-engineering-governance/gitnexus/detected-changes.md create mode 100644 docs/features/GOV-001-engineering-governance/gitnexus/impact-plan.md create mode 100644 docs/features/GOV-001-engineering-governance/implementation-plan.md create mode 100644 docs/features/GOV-001-engineering-governance/manifest.yaml create mode 100644 docs/features/GOV-001-engineering-governance/qa/test-results.md create mode 100644 docs/features/GOV-001-engineering-governance/qa/visual-qa.md create mode 100644 docs/features/GOV-001-engineering-governance/release-notes.md create mode 100644 docs/features/GOV-001-engineering-governance/requirements.md create mode 100644 docs/features/GOV-001-engineering-governance/rollback.md create mode 100644 docs/features/GOV-001-engineering-governance/test-plan.md create mode 100644 docs/gitnexus/architecture-summary.md create mode 100644 docs/gitnexus/history/v0.0.0-governance.md create mode 100644 docs/gitnexus/repository-baseline.md create mode 100644 docs/governance/code-development-standards.md create mode 100644 docs/governance/development-workflow.md create mode 100644 docs/governance/documentation-traceability.md create mode 100644 docs/governance/version-control-and-gitea.md create mode 100644 docs/index.md create mode 100644 package.json create mode 100644 server/.gitkeep create mode 100644 tools/governance/feature-record.mjs create mode 100644 tools/governance/feature-record.test.mjs create mode 100644 tools/governance/finish.mjs create mode 100644 tools/governance/start.mjs create mode 100644 web/.gitkeep diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1014ba7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 0000000..12453dd --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,22 @@ +#!/bin/sh + +# 提交标题必须遵循中文 Conventional Commit。类型与功能编号用于机器检索, +# 冒号后的中文摘要用于人类阅读。合并提交和回退提交由 Git 自动生成,予以放行。 +message_file="$1" +subject="$(sed -n '1p' "$message_file")" + +case "$subject" in + Merge\ *|Revert\ *) + exit 0 + ;; +esac + +if ! printf '%s' "$subject" | grep -Eq '^(feat|fix|docs|refactor|test|chore|build|ci|perf|style)(\([A-Z0-9-]+\))?!?: .+'; then + printf '%s\n' '提交标题格式错误。示例:feat(FEAT-MO-001): 新增市场概览结论区' >&2 + exit 1 +fi + +if ! printf '%s' "$subject" | grep -Eq '[一-龥]'; then + printf '%s\n' '提交摘要必须使用中文。' >&2 + exit 1 +fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aca2c72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# 依赖与构建产物 +node_modules/ +dist/ +coverage/ +*.tsbuildinfo + +# 本地环境与密钥 +.env +.env.* +!.env.example +*.local + +# 编辑器与操作系统 +.DS_Store +.idea/ +.vscode/ + +# GitNexus 索引是可重新生成的本地派生数据,不作为版本回退依据。 +.gitnexus/ +.claude/ +CLAUDE.md + +# 日志与临时文件 +*.log +tmp/ +work/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c8f1602 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,63 @@ +# A 股市场分析工具开发约束 + +本文件是仓库内所有开发代理和开发者必须遵守的入口规范。详细规则见: + +- `docs/governance/code-development-standards.md` +- `docs/governance/development-workflow.md` +- `docs/governance/documentation-traceability.md` +- `docs/governance/version-control-and-gitea.md` + +## 强制要求 + +1. 修改生产代码前必须执行 `npm run governance:start -- <功能编号> <短名称>`,刷新 GitNexus,并完成开发前影响分析。 +2. 修改完成后必须执行测试、构建、视觉验证和 `npm run governance:finish -- <功能编号> <短名称>`,再次刷新 GitNexus并保存前后对比。 +3. 任何功能必须先有 `docs/features/<功能编号>-<短名称>/` 功能档案;没有需求、设计、计划和回退说明不得视为完成。 +4. Git 提交必须使用中文 Conventional Commit,并带功能编号;禁止英文摘要和含糊提交信息。 +5. 代码必须为关键业务逻辑、数据口径、异常恢复和架构取舍提供准确的中文注释;禁止无意义逐行注释。 +6. 文件按稳定职责拆分,不以追求“原子化”为目的过度拆分。优先保证普通开发者能够连续阅读完整业务流程。 +7. 不使用 GitHub。当前只使用本地 Git,远程仓库仅在用户安装 Gitea 后配置。 +8. 禁止提交密钥、真实凭据、生产数据、`.env` 和 GitNexus 本地索引。 + + +# GitNexus — Code Intelligence + +This project is indexed by GitNexus as **a-share-analysis** (170 symbols, 191 relationships, 0 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely. + +> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first. + +## Always Do + +- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user. +- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. +- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits. +- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance. +- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`. + +## Never Do + +- NEVER edit a function, class, or method without first running `gitnexus_impact` on it. +- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis. +- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph. +- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope. + +## Resources + +| Resource | Use for | +|----------|---------| +| `gitnexus://repo/a-share-analysis/context` | Codebase overview, check index freshness | +| `gitnexus://repo/a-share-analysis/clusters` | All functional areas | +| `gitnexus://repo/a-share-analysis/processes` | All execution flows | +| `gitnexus://repo/a-share-analysis/process/{name}` | Step-by-step execution trace | + +## CLI + +| Task | Read this skill file | +|------|---------------------| +| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` | +| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` | +| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` | +| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` | +| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` | +| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` | + + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..60ec674 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# 变更记录 + +本项目采用语义化版本。功能级变化请从 `docs/features/` 按功能编号追溯。 + +## 未发布 + +- 建立工程治理、GitNexus 门禁和功能档案体系。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..d890c2e --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# A-Share Analysis + +A read-only A-share market overview and analysis tool. + +## 当前阶段 + +项目正在建立工程基线,首个业务模块为市场综合概览。当前不包含用户体系、订阅与支付。 + +## Projects + +- `web/`: Vue 3 market terminal frontend. +- `server/`: NestJS API, scheduler, and workers. Added in a later module. +- `deploy/`: MySQL, Redis, and RabbitMQ deployment configuration. Added with the backend module. +- `docs/`: Product and implementation specifications. + +The first implementation slice is the market overview screen in `web/`. + +## 开发入口 + +- [文档索引](docs/index.md) +- [代码开发规范](docs/governance/code-development-standards.md) +- [开发流程规范](docs/governance/development-workflow.md) +- [系统架构](docs/architecture/system-architecture.md) + +开始任何模块前,先阅读根目录 `AGENTS.md`,然后运行: + +```bash +npm run governance:start -- FEAT-MO-001 market-overview +``` + +当前只使用本地 Git。Gitea 安装完成后再按治理文档配置远程仓库。 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..77d6f4c --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.0 diff --git a/deploy/.gitkeep b/deploy/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/deploy/.gitkeep @@ -0,0 +1 @@ + diff --git a/docs/.gitkeep b/docs/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/docs/.gitkeep @@ -0,0 +1 @@ + diff --git a/docs/adr/ADR-0001-monorepo-independent-deploy.md b/docs/adr/ADR-0001-monorepo-independent-deploy.md new file mode 100644 index 0000000..ccb985d --- /dev/null +++ b/docs/adr/ADR-0001-monorepo-independent-deploy.md @@ -0,0 +1,22 @@ +# ADR-0001:采用单仓库、双项目、独立部署 + +- 状态:已接受 +- 日期:2026-08-12 + +## 背景 + +市场概览功能会同时影响前端、API、规则、消息契约和部署配置,需要完整版本关联;API、Scheduler和Worker又必须能够独立运行。 + +## 方案 + +1. 前后端完全分仓:隔离强,但跨仓版本关联和整体回退复杂。 +2. 单仓库双项目:统一历史与图谱,同时独立构建部署。 +3. 单体应用:初期简单,但定时任务和请求链耦合。 + +## 决定 + +采用方案二。前端和后端拥有独立依赖、测试、构建及镜像,但共享 Git 历史、契约、文档和 GitNexus 图谱。 + +## 代价 + +需要维护根目录工作区和跨项目验证脚本;仓库增长后需控制索引与 CI 范围。 diff --git a/docs/adr/ADR-0002-gitnexus-double-gate.md b/docs/adr/ADR-0002-gitnexus-double-gate.md new file mode 100644 index 0000000..546e4d9 --- /dev/null +++ b/docs/adr/ADR-0002-gitnexus-double-gate.md @@ -0,0 +1,16 @@ +# ADR-0002:采用 GitNexus 开发前后双门禁 + +- 状态:已接受 +- 日期:2026-08-12 + +## 背景 + +仅保存代码 diff 无法解释变更影响的调用者、功能分区和执行流程,也无法回答当时为什么修改。 + +## 决定 + +每个功能开发前刷新 GitNexus、读取上下文并完成影响计划;开发后执行实际变更检测、重新索引并保存前后比较。`.gitnexus/` 为可重新生成缓存,不提交;可读报告进入功能档案。 + +## 代价 + +每次开发增加少量文档和索引时间,但换取影响可见、架构可读和历史决策可追溯。 diff --git a/docs/architecture/system-architecture.md b/docs/architecture/system-architecture.md new file mode 100644 index 0000000..4138e6a --- /dev/null +++ b/docs/architecture/system-architecture.md @@ -0,0 +1,41 @@ +# 系统架构 + +## 1. 仓库结构 + +项目采用单 Git 仓库、前后端独立项目和独立部署: + +```text +web/ Vue 3 前端 +server/ NestJS API、Scheduler 与 Worker +contracts/ HTTP 与 RabbitMQ 版本化契约 +deploy/ MySQL、Redis、RabbitMQ 和运行配置 +docs/ 规范、架构、ADR 与功能档案 +tools/ 可重复执行的治理和开发工具 +``` + +选择单仓库是为了让跨前端、后端、消息和部署的同一功能处于一个原子 Git 版本及一张 GitNexus 图谱中;保持独立项目是为了允许单独构建、部署和扩容。 + +## 2. 运行边界 + +```text +免费数据源 + → Scheduler 定时投递 + → RabbitMQ + → 行情采集 Worker + → 指标计算 Worker + → 规则 / AI / 混合分析 + → MySQL 历史事实 + Redis 当前快照 + → NestJS API + → Vue 3 前端 +``` + +- Scheduler只负责触发时间。 +- RabbitMQ只负责任务传递、确认、重试和死信。 +- Worker负责采集、标准化、计算和分析。 +- MySQL保存可追溯事实与历史报告。 +- Redis保存最新快照、缓存、锁和限流状态。 +- Vue前端只读后端 API,不直接接触外部数据源和密钥。 + +## 3. 当前实施顺序 + +第一阶段先实现可交互的市场综合概览和稳定数据契约,再接入正式行情采集链路。用户、邀请、权限、会员和支付后置,不进入当前核心架构。 diff --git a/docs/features/FEAT-MO-001-market-overview/design.md b/docs/features/FEAT-MO-001-market-overview/design.md new file mode 100644 index 0000000..f3df785 --- /dev/null +++ b/docs/features/FEAT-MO-001-market-overview/design.md @@ -0,0 +1,5 @@ +# 设计 + +首屏顺序为:市场结论、驱动与风险、核心指数、市场宽度与量能、板块概览、情绪与资金摘要。分析偏好保存在浏览器本地,页面只显示轻量的当前状态入口。 + +ETF监控、两融数据、大盘云图和实时消息仍是独立一级菜单,不属于短线和中长线切换。 diff --git a/docs/features/FEAT-MO-001-market-overview/implementation-plan.md b/docs/features/FEAT-MO-001-market-overview/implementation-plan.md new file mode 100644 index 0000000..7734490 --- /dev/null +++ b/docs/features/FEAT-MO-001-market-overview/implementation-plan.md @@ -0,0 +1,8 @@ +# 实施计划 + +1. 初始化 Vue 3、Vite、TypeScript和 Dart Sass。 +2. 建立市场快照类型和确定性模拟数据。 +3. 实现终端外壳、数据状态和结论区。 +4. 实现指数、宽度、量能、板块、情绪与资金模块。 +5. 实现分析偏好菜单和依据抽屉。 +6. 完成测试、构建、浏览器验证和视觉对比。 diff --git a/docs/features/FEAT-MO-001-market-overview/manifest.yaml b/docs/features/FEAT-MO-001-market-overview/manifest.yaml new file mode 100644 index 0000000..bf9d340 --- /dev/null +++ b/docs/features/FEAT-MO-001-market-overview/manifest.yaml @@ -0,0 +1,11 @@ +id: FEAT-MO-001 +name: 市场综合概览 +slug: market-overview +status: approved +owner: project +created_at: 2026-08-12 +requirements: requirements.md +design: design.md +implementation_plan: implementation-plan.md +traceability_note: 开发尚未开始,GitNexus与QA证据将在开发门禁执行时创建 +release: unreleased diff --git a/docs/features/FEAT-MO-001-market-overview/requirements.md b/docs/features/FEAT-MO-001-market-overview/requirements.md new file mode 100644 index 0000000..65a8d00 --- /dev/null +++ b/docs/features/FEAT-MO-001-market-overview/requirements.md @@ -0,0 +1,5 @@ +# 需求 + +首屏为“市场概览”模块中的综合概览,采用结论优先。市场概览内部通过轻量分析状态入口切换综合、短线和中长线视角,并支持规则、AI、混合与对照分析。 + +当前切片仅开发 Vue 3 可交互首屏和本地模拟数据,不接用户体系和正式数据链路。 diff --git a/docs/features/FEAT-MO-001-market-overview/test-plan.md b/docs/features/FEAT-MO-001-market-overview/test-plan.md new file mode 100644 index 0000000..7885192 --- /dev/null +++ b/docs/features/FEAT-MO-001-market-overview/test-plan.md @@ -0,0 +1,8 @@ +# 测试计划 + +- 结论、驱动和风险在首屏可见。 +- 分析状态可以临时切换并保存默认值。 +- 依据抽屉能够打开和关闭。 +- 时间范围切换更新图表。 +- 加载、部分数据、过期和错误状态具有明确文案。 +- 桌面和窄窗口不出现阻断核心内容的溢出。 diff --git a/docs/features/GOV-001-engineering-governance/design.md b/docs/features/GOV-001-engineering-governance/design.md new file mode 100644 index 0000000..4f96ecd --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/design.md @@ -0,0 +1,11 @@ +# 设计 + +采用仓库级规范、功能级档案和自动化门禁三层结构。 + +- `AGENTS.md` 为代理和开发者的强制入口。 +- `docs/governance/` 保存长期规范。 +- `docs/features/` 保存每次功能的需求、设计、测试、GitNexus 前后报告、发布和回退。 +- `tools/governance/` 提供一致的开发前和开发后入口。 +- `.githooks/commit-msg` 在本地阻止非中文或不符合格式的提交。 + +GitNexus 索引不提交,因为它可以重新生成;分析摘要必须提交,因为它是历史决策证据。 diff --git a/docs/features/GOV-001-engineering-governance/gitnexus/after.md b/docs/features/GOV-001-engineering-governance/gitnexus/after.md new file mode 100644 index 0000000..dd9a4a3 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/gitnexus/after.md @@ -0,0 +1,8 @@ +# GitNexus 开发后基线 + +- 日期:2026-08-12 +- GitNexus状态:最新。 +- 图谱规模:170 个符号、191 条关系、4 个功能簇、0 条执行流程。 +- 远程仓库:未配置。 + +图谱已识别治理脚本中的功能编号校验、目录解析和门禁执行关系,并形成 4 个治理相关功能簇。查询“engineering governance feature record”能够定位功能编号校验、必备文件清单、开始/完成门禁及对应文档。仓库尚无业务代码,因此没有业务执行流程属于符合预期的结果。 diff --git a/docs/features/GOV-001-engineering-governance/gitnexus/before.md b/docs/features/GOV-001-engineering-governance/gitnexus/before.md new file mode 100644 index 0000000..578ec4e --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/gitnexus/before.md @@ -0,0 +1,8 @@ +# GitNexus 开发前基线 + +- 日期:2026-08-12 +- Git 状态:空仓库,尚无提交。 +- GitNexus:20 个节点、16 条关系、0 个功能簇、0 条执行流程。 +- 远程仓库:未配置。 + +当前只有项目说明、空的前后端目录和市场概览初步计划,不存在可受影响的生产代码符号。 diff --git a/docs/features/GOV-001-engineering-governance/gitnexus/comparison.md b/docs/features/GOV-001-engineering-governance/gitnexus/comparison.md new file mode 100644 index 0000000..45367f3 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/gitnexus/comparison.md @@ -0,0 +1,10 @@ +# GitNexus 前后比较 + +| 项目 | 开发前 | 开发后 | 说明 | +|---|---:|---:|---| +| 符号 | 20 | 170 | 新增治理脚本、规范和功能档案中的可索引结构 | +| 关系 | 16 | 191 | 新增脚本导入、调用与文档关联 | +| 功能簇 | 0 | 4 | 形成治理相关功能簇,尚无业务功能簇 | +| 执行流程 | 0 | 0 | 尚未开始业务应用代码开发 | + +实际变化与开发前计划一致,影响限制在工程治理层。暂存区变更检测识别 46 个文件、118 个符号、0 条受影响流程,风险为低;未发现 API、数据模型、消息契约、部署或界面方面的计划外变化。 diff --git a/docs/features/GOV-001-engineering-governance/gitnexus/detected-changes.md b/docs/features/GOV-001-engineering-governance/gitnexus/detected-changes.md new file mode 100644 index 0000000..0111cb5 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/gitnexus/detected-changes.md @@ -0,0 +1,21 @@ +# 实际变更检测 + +## 实际范围 + +- 新增仓库级规范、系统架构、ADR、功能档案和文档索引。 +- 新增功能档案校验、开发前索引和开发后完成门禁脚本。 +- 新增中文提交信息钩子和本地 Git 配置说明。 +- 更新 `AGENTS.md`,保留 GitNexus 自动管理区块,并在其外加入项目强制规则。 + +## 计划外影响检查 + +首次执行变更检测时因空仓库没有 `HEAD` 而失败。创建中文空基线提交 `7cc2ba0` 后,使用暂存区范围重新执行: + +```text +npx gitnexus detect-changes --repo a-share-analysis --scope staged +Changes: 46 files, 118 symbols +Affected processes: 0 +Risk level: low +``` + +没有业务生产代码、HTTP API、数据库结构、RabbitMQ消息、部署配置或用户界面变化。实际范围与计划一致。 diff --git a/docs/features/GOV-001-engineering-governance/gitnexus/impact-plan.md b/docs/features/GOV-001-engineering-governance/gitnexus/impact-plan.md new file mode 100644 index 0000000..2d2a0c5 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/gitnexus/impact-plan.md @@ -0,0 +1,18 @@ +# 开发前影响计划 + +## 计划影响 + +- 新增仓库级规范、功能档案、ADR和治理工具。 +- 更新 `AGENTS.md` 与 `README.md` 的开发入口。 +- 不修改业务生产代码,不改变 API、数据库、RabbitMQ消息和页面行为。 + +## GitNexus 风险 + +初始仓库没有业务调用流程和现有生产符号。治理代码完成后,对核心符号 `validateFeatureId` 执行上游影响分析: + +- 直接依赖:`tools/governance/start.mjs`、`tools/governance/finish.mjs`。 +- 受影响执行流程:0。 +- 受影响模块:0。 +- GitNexus风险等级:低。 + +该符号仍需通过行为测试保护,因为错误放宽编号格式会同时削弱开发前和开发后门禁。 diff --git a/docs/features/GOV-001-engineering-governance/implementation-plan.md b/docs/features/GOV-001-engineering-governance/implementation-plan.md new file mode 100644 index 0000000..a1bddda --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/implementation-plan.md @@ -0,0 +1,9 @@ +# 实施计划 + +1. 初始化本地 Git 与首次 GitNexus 索引。 +2. 建立代码、流程、追溯、Git/Gitea规范。 +3. 建立系统架构与 ADR。 +4. 用测试先行实现功能编号和档案清单校验。 +5. 实现开发前后 GitNexus 门禁脚本。 +6. 建立 GOV-001 与 FEAT-MO-001 功能档案。 +7. 执行测试、脚本检查、GitNexus重建并提交中文基线。 diff --git a/docs/features/GOV-001-engineering-governance/manifest.yaml b/docs/features/GOV-001-engineering-governance/manifest.yaml new file mode 100644 index 0000000..4a093b5 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/manifest.yaml @@ -0,0 +1,17 @@ +id: GOV-001 +name: 工程治理基线 +slug: engineering-governance +status: verifying +owner: project +created_at: 2026-08-12 +requirements: requirements.md +design: design.md +implementation_plan: implementation-plan.md +decisions: + - ../../adr/ADR-0001-monorepo-independent-deploy.md + - ../../adr/ADR-0002-gitnexus-double-gate.md +gitnexus_before: gitnexus/before.md +gitnexus_after: gitnexus/after.md +gitnexus_comparison: gitnexus/comparison.md +baseline_commit: 7cc2ba0 +release: unreleased diff --git a/docs/features/GOV-001-engineering-governance/qa/test-results.md b/docs/features/GOV-001-engineering-governance/qa/test-results.md new file mode 100644 index 0000000..e8cd180 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/qa/test-results.md @@ -0,0 +1,27 @@ +# 测试结果 + +- 日期:2026-08-12 +- Node.js:v20.20.2 + +## 已执行 + +```text +npm run test:governance +结果:4 个测试通过,0 个失败。 + +node --check tools/governance/start.mjs +结果:通过。 + +node --check tools/governance/finish.mjs +结果:通过。 + +npm run governance:finish -- GOV-001 engineering-governance +结果:基础门禁通过。 +``` + +中文提交钩子另外验证规范中文示例通过、英文摘要被拒绝。 + +```text +规范中文提交:退出码 0 +英文摘要提交:退出码 1 +``` diff --git a/docs/features/GOV-001-engineering-governance/qa/visual-qa.md b/docs/features/GOV-001-engineering-governance/qa/visual-qa.md new file mode 100644 index 0000000..e8164bc --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/qa/visual-qa.md @@ -0,0 +1,3 @@ +# 视觉 QA + +本功能不修改用户界面,因此不适用视觉对比。后续页面功能必须保存同视口参考图和实现图。 diff --git a/docs/features/GOV-001-engineering-governance/release-notes.md b/docs/features/GOV-001-engineering-governance/release-notes.md new file mode 100644 index 0000000..a875f75 --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/release-notes.md @@ -0,0 +1,3 @@ +# 发布说明 + +建立项目首个工程治理基线,不包含用户可见业务功能。 diff --git a/docs/features/GOV-001-engineering-governance/requirements.md b/docs/features/GOV-001-engineering-governance/requirements.md new file mode 100644 index 0000000..df3542d --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/requirements.md @@ -0,0 +1,14 @@ +# 需求 + +## 目标 + +建立可直接阅读、可比较、可追溯和可回退的工程治理基线。 + +## 必须满足 + +- 分别提供代码开发规范和开发流程规范。 +- 关键代码必须包含解释业务口径和设计原因的中文注释。 +- 代码按常规阅读尺度拆分,禁止过度碎片化。 +- 所有提交使用中文 Conventional Commit并关联功能编号。 +- 每次开发前后均刷新 GitNexus并保存可读报告。 +- 当前只使用本地 Git,未来接入用户自建 Gitea,不使用 GitHub。 diff --git a/docs/features/GOV-001-engineering-governance/rollback.md b/docs/features/GOV-001-engineering-governance/rollback.md new file mode 100644 index 0000000..63196aa --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/rollback.md @@ -0,0 +1,3 @@ +# 回退说明 + +在本地首个提交建立后,可通过该提交完整读取治理基线。若治理脚本阻塞开发,可先用 Git 恢复到上一标签;不得删除功能档案或改写已共享历史。 diff --git a/docs/features/GOV-001-engineering-governance/test-plan.md b/docs/features/GOV-001-engineering-governance/test-plan.md new file mode 100644 index 0000000..e43251c --- /dev/null +++ b/docs/features/GOV-001-engineering-governance/test-plan.md @@ -0,0 +1,8 @@ +# 测试计划 + +- 验证合法和非法功能编号。 +- 验证功能目录只能解析到 `docs/features/`。 +- 验证完成门禁的必备文件清单。 +- 验证中文提交钩子接受规范示例并拒绝英文摘要。 +- 验证 GitNexus 索引在修改后可成功重建。 +- 验证仓库未配置远程地址。 diff --git a/docs/gitnexus/architecture-summary.md b/docs/gitnexus/architecture-summary.md new file mode 100644 index 0000000..5e7498f --- /dev/null +++ b/docs/gitnexus/architecture-summary.md @@ -0,0 +1,11 @@ +# GitNexus 架构摘要 + +## 当前可识别模块 + +- 工程治理:功能编号校验、功能档案路径、开发前索引、开发后完成门禁。 +- 文档治理:代码规范、流程规范、追溯规范、Git/Gitea规范。 +- 功能规划:GOV-001 工程治理与 FEAT-MO-001 市场综合概览。 + +## 预期演进 + +业务代码加入后,图谱应逐步形成前端市场概览、后端 API、行情适配、指标计算和分析引擎等功能簇。每次发布后的实际簇和执行流程记录到 `docs/gitnexus/history/`,不得用预期结构冒充 GitNexus 实际识别结果。 diff --git a/docs/gitnexus/history/v0.0.0-governance.md b/docs/gitnexus/history/v0.0.0-governance.md new file mode 100644 index 0000000..1603167 --- /dev/null +++ b/docs/gitnexus/history/v0.0.0-governance.md @@ -0,0 +1,11 @@ +# v0.0.0 工程治理图谱摘要 + +这是首个本地治理基线,尚未发布业务功能。 + +- 170 个符号 +- 191 条关系 +- 4 个功能簇 +- 0 条执行流程 +- 未配置远程仓库 + +对应功能档案:`docs/features/GOV-001-engineering-governance/`。 diff --git a/docs/gitnexus/repository-baseline.md b/docs/gitnexus/repository-baseline.md new file mode 100644 index 0000000..ef1cb58 --- /dev/null +++ b/docs/gitnexus/repository-baseline.md @@ -0,0 +1,8 @@ +# GitNexus 仓库基线 + +- 仓库:`a-share-analysis` +- 建立日期:2026-08-12 +- 基线阶段:工程治理 +- 图谱:170 个符号、191 条关系、4 个功能簇、0 条执行流程 + +当前图谱主要由治理脚本、规范和功能档案构成。业务代码尚未开始,因此功能簇与执行流程为空。市场概览开始开发前必须再次运行 GitNexus,届时本文件通过 Git 历史保留本次基线,不覆盖历史事实。 diff --git a/docs/governance/code-development-standards.md b/docs/governance/code-development-standards.md new file mode 100644 index 0000000..5f4f4d1 --- /dev/null +++ b/docs/governance/code-development-standards.md @@ -0,0 +1,115 @@ +# 代码开发规范 + +## 1. 目标 + +本规范保证代码对普通开发者可连续阅读、对关键业务可解释、对历史版本可维护。规范适用于 Vue 3 前端、NestJS 后端、调度器、RabbitMQ Worker、数据适配器、规则引擎和 AI 分析模块。 + +## 2. 技术基线 + +- 前端:Vue 3、Vite、TypeScript、Dart Sass、Naive UI。 +- 后端:NestJS、TypeScript。 +- 数据库:MySQL;缓存:Redis;消息队列:RabbitMQ。 +- 图表:Lightweight Charts负责K线和分时,ECharts负责热力图、分布和资金趋势。 +- AI:由服务端调用兼容 OpenAI 格式的付费 API,密钥不得下发浏览器。 + +依赖版本必须由锁文件固定。引入新依赖前应说明用途、替代方案、体积或运行成本以及退出方案。 + +## 3. 文件组织与拆分尺度 + +代码按业务能力组织,而不是把每个函数、类型和常量拆成独立文件。 + +### 应当拆分 + +- 文件同时承担两个可独立变化的业务职责。 +- 模块形成稳定复用边界,且确实被多个调用方使用。 +- 单个文件已经难以在一次正常阅读中理解完整流程。 +- 外部系统适配、持久化、消息传输与纯业务计算需要隔离测试。 + +### 不应拆分 + +- 只为减少行数创建单函数文件。 +- 将同一业务流程拆成大量需要来回跳转的薄包装。 +- 为尚未出现的复用场景提前抽象。 +- 为形式上的“分层”添加不产生业务价值的转发层。 + +Vue 页面可以包含与页面强绑定的小型展示逻辑;当子区域拥有独立状态、独立测试价值或被复用时再提取组件。NestJS 模块应让入口、服务和领域计算的调用关系容易跟读。 + +## 4. 命名与语言 + +- 文件、变量、函数、类型和数据库字段使用清晰英文命名。 +- 产品文案、业务日志、错误说明、代码注释和提交摘要优先使用中文。 +- 禁止 `data1`、`temp2`、`handleThing` 等缺乏语义的命名。 +- A 股领域词汇使用统一词典,例如 `limitUpCount`、`brokenBoardRate`、`marketBreadth`。 +- 时间字段必须体现语义,例如 `tradeDate`、`snapshotAt`、`sourceUpdatedAt`,不得统称 `time`。 + +## 5. 注释规范 + +代码必须写详细但有信息价值的中文注释。注释解释“为什么、口径、限制和风险”,不复述语法。 + +### 必须注释 + +- 对外导出的公共接口、类型和关键函数。 +- 涨跌停、复权、停牌、午间休市等 A 股特殊规则。 +- 指标公式、阈值来源、单位、数据日期和缺失值处理。 +- RabbitMQ 的幂等、重试、死信和消息顺序假设。 +- Redis 与 MySQL 一致性边界和缓存失效策略。 +- AI 输入裁剪、事实约束、降级和成本控制逻辑。 +- 看似可以简化但因兼容性或历史原因必须保留的实现。 +- 异常恢复、降级策略和安全边界。 + +### 禁止注释 + +```ts +// 将 count 加一 +count += 1; +``` + +此类注释没有提供代码之外的信息。代码变更时,注释必须同步更新;失真的注释视为缺陷。 + +## 6. 类型与数据契约 + +- 禁止无理由使用 `any`;外部输入先以 `unknown` 接收并校验。 +- HTTP API 使用版本化 OpenAPI 契约。 +- RabbitMQ 事件包含 `eventId`、`eventType`、`schemaVersion`、`occurredAt`、`tradeDate`、`traceId` 和 `idempotencyKey`。 +- 金额、成交额和比率必须明确单位,避免同一字段混用元、万元、亿元或百分比小数。 +- 数据来源、采集时间、交易日期、完整性和口径版本必须可追溯。 + +## 7. 错误处理与日志 + +- 不吞异常,不使用空 `catch`。 +- 对外错误不泄露密钥、内部地址和原始上游响应。 +- 日志使用结构化字段,至少包含 `traceId`、任务类型、交易日期和数据源。 +- 免费数据源失败时保留最后有效快照,并明确标记陈旧,禁止伪装实时数据。 +- AI 失败不得影响规则分析和基础行情展示。 + +## 8. 前端规范 + +- 页面不得直接访问第三方行情源、Redis、RabbitMQ 或 AI 服务。 +- 全局服务器状态使用 TanStack Vue Query,本地界面偏好使用 Pinia或轻量组合式函数。 +- Sass token集中管理颜色、间距、圆角、字号和断点。 +- A 股默认红涨绿跌,但状态必须同时提供文字或形状,不能只依赖颜色。 +- 图表必须标注单位、时间范围、数据日期和更新时间。 +- 所有核心交互覆盖加载、空、部分数据、错误和过期状态。 + +## 9. 后端与任务规范 + +- API、Scheduler和Worker作为独立进程维护,不在请求期间临时抓取全市场数据。 +- Scheduler只决定何时投递;RabbitMQ负责任务传输;Worker负责执行;MySQL负责事实记录;Redis负责当前快照和短期状态。 +- 消费者必须幂等,消息确认只能发生在持久化或可验证处理完成后。 +- 免费数据源通过 Adapter 统一为内部模型,上层不得依赖供应商原始字段。 + +## 10. 测试要求 + +- 功能和缺陷修复遵循测试先行:先看到测试因缺少行为而失败,再实现最小代码。 +- 纯规则和指标计算使用单元测试,期望值必须手工推导。 +- 数据源 Adapter 使用契约测试和固定样本。 +- HTTP 与 RabbitMQ 使用契约测试。 +- 关键页面使用 Playwright流程测试和视觉截图对比。 +- 合并前必须通过类型检查、测试、构建和适用的视觉验证。 + +## 11. 安全要求 + +- 禁止提交 `.env`、API Key、密码、真实账号和生产数据。 +- AI 密钥、数据源凭证和支付凭证仅存在服务端密钥管理中。 +- SQL必须参数化;外部输入必须在边界处校验。 +- 日志和异常报告必须脱敏。 diff --git a/docs/governance/development-workflow.md b/docs/governance/development-workflow.md new file mode 100644 index 0000000..f640bb1 --- /dev/null +++ b/docs/governance/development-workflow.md @@ -0,0 +1,98 @@ +# 开发流程规范 + +## 1. 总原则 + +每个步骤必须留痕、可以直接阅读、可以比较、可以关联到 Git 提交并有明确回退方法。功能开发以功能编号为主键,禁止先写代码、后补需求和设计。 + +## 2. 功能状态 + +```text +proposed → designing → approved → developing → verifying → released + ↘ blocked +released → superseded +``` + +状态只能在证据齐全时前进。`released` 必须对应 Git 提交和版本;被替代的设计保留原文并标记 `superseded`,不得删除历史原因。 + +## 3. 开发前流程 + +1. 分配功能编号和英文短名称。 +2. 建立 `docs/features/<编号>-<短名称>/`。 +3. 填写需求、范围、非目标和验收标准。 +4. 比较可选方案,记录设计与关键决策。 +5. 更新 API、事件和数据结构契约。 +6. 编写测试计划和实施计划。 +7. 确保 Git 工作区基线可识别,执行: + +```bash +npm run governance:start -- FEAT-MO-001 market-overview +``` + +8. 运行 GitNexus 查询、上下文和影响分析,将结果写入 `gitnexus/impact-plan.md`。 +9. 高风险或关键路径变化必须先向用户说明影响,再进入开发。 + +开发前必须至少回答:修改什么、为什么修改、影响谁、如何验证、失败后如何回退。 + +## 4. 开发过程 + +- 使用短期功能分支;当前仓库基线建立阶段经用户明确确认后可直接在 `main` 工作。 +- 每个可观察行为先写失败测试,再实现最小代码并重构。 +- 需求或设计发生变化时,先更新功能档案并记录原因,再改代码。 +- 每个阶段保存必要截图和测试结果,禁止只在聊天中保留决定。 +- 发现缺陷时先记录复现步骤和失败测试,禁止无证据猜测式修复。 + +## 5. 开发后流程 + +1. 完成类型检查、单元测试、契约测试、构建和页面流程测试。 +2. 对界面变化保存参考图、实现图和同视口对比结果。 +3. 查看 Git diff,确认没有计划外文件和密钥。 +4. 执行 GitNexus 变更检测;若 MCP 工具不可用,记录限制并至少保存 Git diff 与重新索引结果。 +5. 再次运行: + +```bash +npm run governance:finish -- FEAT-MO-001 market-overview +``` + +6. 填写 `gitnexus/after.md`、`detected-changes.md` 和 `comparison.md`。 +7. 更新发布说明、回退说明、变更记录和版本号。 +8. 使用中文 Conventional Commit提交。 +9. 提交后执行 `npx gitnexus status`;若状态过期,再运行 `npx gitnexus analyze`。 + +## 6. 完成定义 + +下列任一项缺失,功能不得标记完成: + +- 需求和设计已确认。 +- 实施计划与实际变化一致。 +- 代码符合开发规范并包含必要中文注释。 +- 测试和构建有最新成功证据。 +- 视觉变化有同视口对比证据。 +- GitNexus 开发前后报告和差异说明齐全。 +- 发布说明和回退方法可执行。 +- 中文提交已关联功能编号。 + +## 7. 提交流程 + +提交格式: + +```text +<类型>(<功能编号>): <中文摘要> +``` + +示例: + +```text +feat(FEAT-MO-001): 新增市场概览结论区 +fix(FEAT-MO-001): 修正成交额同比计算口径 +docs(GOV-001): 建立工程治理与追溯规范 +``` + +一次提交应表达一个完整意图,但不为了追求小提交把同一功能切成无法独立理解的碎片。 + +## 8. 发布与回退 + +- 使用语义化版本和带注释 Git Tag。 +- 发布产物必须对应确定提交,不从浮动分支临时构建。 +- 应用优先通过部署上一不可变镜像回退。 +- 数据库采用可兼容迁移和前向修复,破坏性回滚需先备份和演练。 +- 规则、提示词和消息契约发布后不得原地覆盖,只能新增版本。 diff --git a/docs/governance/documentation-traceability.md b/docs/governance/documentation-traceability.md new file mode 100644 index 0000000..b0f931f --- /dev/null +++ b/docs/governance/documentation-traceability.md @@ -0,0 +1,43 @@ +# 文档与追溯规范 + +## 1. 追溯主键 + +每个业务变化必须有唯一功能编号。功能编号贯穿需求、设计、ADR、代码提交、测试、截图、GitNexus 报告、发布和回退。 + +## 2. 功能档案必备内容 + +```text +docs/features/<编号>-<短名称>/ +├── manifest.yaml +├── requirements.md +├── design.md +├── implementation-plan.md +├── test-plan.md +├── gitnexus/ +│ ├── before.md +│ ├── impact-plan.md +│ ├── detected-changes.md +│ ├── after.md +│ └── comparison.md +├── screenshots/ +│ ├── reference/ +│ ├── iterations/ +│ └── released/ +├── qa/ +│ ├── test-results.md +│ └── visual-qa.md +├── release-notes.md +└── rollback.md +``` + +## 3. 历史保留 + +- 已发布文档不删除、不覆盖历史结论;修订通过 Git 历史和文档版本说明保留。 +- 重大方案变化新增 ADR,旧 ADR 标记被替代。 +- 规则、提示词、API 和事件契约使用明确版本。 +- 截图文件名包含页面、状态、视口和版本,例如 `market-overview-trading-1440x1200-v0.1.0.png`。 +- `.gitnexus/` 不提交;可读的 GitNexus 摘要和比较报告必须提交。 + +## 4. 可阅读性 + +文档先写结论,再写背景、方案和证据。禁止使用“见聊天记录”“以后再说”“大概如此”作为正式设计依据。链接使用仓库相对路径,保证在本地与 Gitea 中均可阅读。 diff --git a/docs/governance/version-control-and-gitea.md b/docs/governance/version-control-and-gitea.md new file mode 100644 index 0000000..5dd7709 --- /dev/null +++ b/docs/governance/version-control-and-gitea.md @@ -0,0 +1,40 @@ +# Git 与 Gitea 规范 + +## 1. 当前策略 + +当前只使用本地 Git,不配置 GitHub、不创建 GitHub Actions,也不向任何第三方远程仓库推送。用户安装 Gitea 后,再显式配置 `origin`。 + +## 2. 分支与提交 + +- `main` 始终保持可验证和可回退。 +- 普通功能使用 `feature/<功能编号>-<短名称>`。 +- 修复使用 `fix/<功能编号>-<短名称>`。 +- 提交必须符合中文 Conventional Commit,仓库通过 `.githooks/commit-msg`检查。 +- 禁止强推共享 `main`,禁止使用破坏历史的回退方式处理已共享版本。 + +首次克隆后执行: + +```bash +git config core.hooksPath .githooks +``` + +## 3. Gitea 接入 + +Gitea 安装并创建空仓库后,由用户确认地址,再执行: + +```bash +git remote add origin <用户提供的Gitea仓库地址> +git push -u origin main +``` + +建议在 Gitea 中保护 `main`:禁止强推、要求状态检查通过、要求变更说明关联功能编号。未得到用户提供的地址和授权前,任何代理不得自行添加远程或推送。 + +## 4. 版本与标签 + +发布使用带注释标签,例如: + +```bash +git tag -a v0.1.0 -m "发布市场综合概览 v0.1.0" +``` + +标签必须指向通过验证的提交。应用回退优先选择既有标签和不可变构建产物,而不是重新拼装旧版本。 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..fe03226 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,27 @@ +# 项目文档索引 + +## 必读规范 + +- [代码开发规范](governance/code-development-standards.md) +- [开发流程规范](governance/development-workflow.md) +- [文档与追溯规范](governance/documentation-traceability.md) +- [Git 与 Gitea 规范](governance/version-control-and-gitea.md) + +## 架构与决策 + +- [系统架构](architecture/system-architecture.md) +- [ADR-0001:单仓库双项目独立部署](adr/ADR-0001-monorepo-independent-deploy.md) +- [ADR-0002:GitNexus 双门禁](adr/ADR-0002-gitnexus-double-gate.md) + +## GitNexus + +- [仓库基线](gitnexus/repository-baseline.md) +- [当前架构摘要](gitnexus/architecture-summary.md) +- [图谱历史](gitnexus/history/v0.0.0-governance.md) + +## 功能档案 + +- [GOV-001:工程治理基线](features/GOV-001-engineering-governance/manifest.yaml) +- [FEAT-MO-001:市场综合概览](features/FEAT-MO-001-market-overview/manifest.yaml) + +功能档案是需求、设计、代码、测试、版本和回退之间的唯一正式关联入口。 diff --git a/package.json b/package.json new file mode 100644 index 0000000..ceb5c54 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "a-share-analysis-workspace", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "test:governance": "node --test tools/governance/feature-record.test.mjs", + "governance:start": "node tools/governance/start.mjs", + "governance:finish": "node tools/governance/finish.mjs" + } +} diff --git a/server/.gitkeep b/server/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/server/.gitkeep @@ -0,0 +1 @@ + diff --git a/tools/governance/feature-record.mjs b/tools/governance/feature-record.mjs new file mode 100644 index 0000000..cb4de14 --- /dev/null +++ b/tools/governance/feature-record.mjs @@ -0,0 +1,51 @@ +import path from 'node:path'; + +const FEATURE_ID_PATTERN = /^(?:FEAT-[A-Z]{2,8}|GOV)-\d{3}$/; + +const REQUIRED_FEATURE_FILES = Object.freeze([ + 'manifest.yaml', + 'requirements.md', + 'design.md', + 'implementation-plan.md', + 'test-plan.md', + 'gitnexus/before.md', + 'gitnexus/impact-plan.md', + 'gitnexus/detected-changes.md', + 'gitnexus/after.md', + 'gitnexus/comparison.md', + 'qa/test-results.md', + 'qa/visual-qa.md', + 'release-notes.md', + 'rollback.md', +]); + +/** + * 功能编号是需求、设计、代码提交、测试结果和发布记录之间的主关联键。 + * 严格限制格式可以避免路径穿越、临时名称以及后续无法检索的模糊编号。 + */ +export function validateFeatureId(featureId) { + return FEATURE_ID_PATTERN.test(featureId); +} + +/** + * 功能目录只允许位于 docs/features 下。短名称继续使用英文 kebab-case, + * 便于命令行、URL 和跨平台文件系统稳定处理;面向人的名称保存在 manifest 中。 + */ +export function getFeatureDirectory(repositoryRoot, featureId, slug) { + if (!validateFeatureId(featureId)) { + throw new Error(`功能编号格式无效:${featureId}`); + } + + if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)) { + throw new Error(`功能短名称必须使用 kebab-case:${slug}`); + } + + return path.join(repositoryRoot, 'docs', 'features', `${featureId}-${slug}`); +} + +/** + * 返回副本,防止调用方修改共享清单后绕过完成门禁。 + */ +export function getRequiredFeatureFiles() { + return [...REQUIRED_FEATURE_FILES]; +} diff --git a/tools/governance/feature-record.test.mjs b/tools/governance/feature-record.test.mjs new file mode 100644 index 0000000..c017e2c --- /dev/null +++ b/tools/governance/feature-record.test.mjs @@ -0,0 +1,45 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { + getFeatureDirectory, + getRequiredFeatureFiles, + validateFeatureId, +} from './feature-record.mjs'; + +test('接受带业务域和三位序号的功能编号', () => { + assert.equal(validateFeatureId('FEAT-MO-001'), true); + assert.equal(validateFeatureId('GOV-001'), true); +}); + +test('拒绝无法追溯或格式含糊的功能编号', () => { + assert.equal(validateFeatureId('market-overview'), false); + assert.equal(validateFeatureId('FEAT-MO-1'), false); + assert.equal(validateFeatureId('../FEAT-MO-001'), false); +}); + +test('将功能编号和短名称解析到固定的功能档案目录', () => { + assert.equal( + getFeatureDirectory('/repo', 'FEAT-MO-001', 'market-overview'), + '/repo/docs/features/FEAT-MO-001-market-overview', + ); +}); + +test('返回开发完成前必须存在的完整追溯文件清单', () => { + assert.deepEqual(getRequiredFeatureFiles(), [ + 'manifest.yaml', + 'requirements.md', + 'design.md', + 'implementation-plan.md', + 'test-plan.md', + 'gitnexus/before.md', + 'gitnexus/impact-plan.md', + 'gitnexus/detected-changes.md', + 'gitnexus/after.md', + 'gitnexus/comparison.md', + 'qa/test-results.md', + 'qa/visual-qa.md', + 'release-notes.md', + 'rollback.md', + ]); +}); diff --git a/tools/governance/finish.mjs b/tools/governance/finish.mjs new file mode 100644 index 0000000..8869dab --- /dev/null +++ b/tools/governance/finish.mjs @@ -0,0 +1,65 @@ +import { execFileSync } from 'node:child_process'; +import { existsSync, readFileSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; + +import { + getFeatureDirectory, + getRequiredFeatureFiles, + validateFeatureId, +} from './feature-record.mjs'; + +const [featureId, slug] = process.argv.slice(2); +const repositoryRoot = process.cwd(); + +if (!featureId || !slug || !validateFeatureId(featureId)) { + throw new Error('用法:npm run governance:finish -- <功能编号> <英文短名称>'); +} + +const featureDirectory = getFeatureDirectory(repositoryRoot, featureId, slug); +if (!existsSync(featureDirectory)) { + throw new Error(`功能档案不存在:${featureDirectory}`); +} + +function run(command, args) { + return execFileSync(command, args, { + cwd: repositoryRoot, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + }).trim(); +} + +/** + * 完成门禁先验证仓库自身的治理测试,再刷新 GitNexus。业务项目接入后, + * 根目录 verify 脚本会继续串联前端和后端测试,而不需要改变本门禁入口。 + */ +run('npm', ['run', 'test:governance']); +run('npx', ['gitnexus', 'analyze']); + +const status = run('npx', ['gitnexus', 'status']); +const diffSummary = run('git', ['diff', '--stat']) || '(没有未提交差异)'; +const worktreeSummary = run('git', ['status', '--short']) || '(工作区干净)'; +const afterReport = path.join(featureDirectory, 'gitnexus', 'after.md'); + +if (!existsSync(afterReport) || readFileSync(afterReport, 'utf8').trim().length === 0) { + writeFileSync( + afterReport, + `# GitNexus 开发后基线\n\n` + + `## GitNexus 状态\n\n\`\`\`text\n${status}\n\`\`\`\n\n` + + `## Git 已跟踪变更摘要\n\n\`\`\`text\n${diffSummary}\n\`\`\`\n\n` + + `## Git 工作区摘要\n\n\`\`\`text\n${worktreeSummary}\n\`\`\`\n`, + 'utf8', + ); +} + +const missingFiles = getRequiredFeatureFiles().filter((relativeFile) => { + const file = path.join(featureDirectory, relativeFile); + return !existsSync(file) || readFileSync(file, 'utf8').trim().length === 0; +}); + +if (missingFiles.length > 0) { + throw new Error(`完成门禁未通过,缺少或为空:\n- ${missingFiles.join('\n- ')}`); +} + +process.stdout.write( + `基础门禁已通过。提交前仍须人工确认 GitNexus 影响报告、业务测试、视觉 QA 和回退说明。\n`, +); diff --git a/tools/governance/start.mjs b/tools/governance/start.mjs new file mode 100644 index 0000000..52fcd89 --- /dev/null +++ b/tools/governance/start.mjs @@ -0,0 +1,63 @@ +import { execFileSync } from 'node:child_process'; +import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; + +import { getFeatureDirectory, validateFeatureId } from './feature-record.mjs'; + +const [featureId, slug] = process.argv.slice(2); +const repositoryRoot = process.cwd(); + +if (!featureId || !slug || !validateFeatureId(featureId)) { + throw new Error('用法:npm run governance:start -- <功能编号> <英文短名称>'); +} + +const featureDirectory = getFeatureDirectory(repositoryRoot, featureId, slug); +const gitnexusDirectory = path.join(featureDirectory, 'gitnexus'); +const beforeReport = path.join(gitnexusDirectory, 'before.md'); + +if (existsSync(beforeReport)) { + throw new Error(`开发前报告已存在,为保护历史不会覆盖:${beforeReport}`); +} + +mkdirSync(gitnexusDirectory, { recursive: true }); + +/** + * 开发门禁直接调用参数数组,不拼接 shell 字符串,避免功能名称被解释为命令。 + * stdio 使用 pipe 是为了把同一次运行的真实输出固化到功能档案中。 + */ +function run(command, args) { + return execFileSync(command, args, { + cwd: repositoryRoot, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + }).trim(); +} + +const branch = run('git', ['branch', '--show-current']) || '(尚无分支)'; +const commit = run('git', ['rev-parse', '--verify', 'HEAD']).slice(0, 12); +const worktree = run('git', ['status', '--short']) || '(干净)'; + +run('npx', ['gitnexus', 'analyze']); +const gitnexusStatus = run('npx', ['gitnexus', 'status']); +const createdAt = new Intl.DateTimeFormat('zh-CN', { + dateStyle: 'long', + timeStyle: 'long', + timeZone: 'Asia/Shanghai', +}).format(new Date()); + +writeFileSync( + beforeReport, + `# GitNexus 开发前基线\n\n` + + `- 功能编号:${featureId}\n` + + `- 记录时间:${createdAt}\n` + + `- 分支:${branch}\n` + + `- 基线提交:${commit}\n\n` + + `## 工作区\n\n\`\`\`text\n${worktree}\n\`\`\`\n\n` + + `## GitNexus 状态\n\n\`\`\`text\n${gitnexusStatus}\n\`\`\`\n\n` + + `## 后续人工分析\n\n` + + `在修改代码前,将 GitNexus query、context、impact 的结论写入 ` + + `\`gitnexus/impact-plan.md\`。高风险结果必须先获得用户确认。\n`, + 'utf8', +); + +process.stdout.write(`已创建开发前基线:${beforeReport}\n`); diff --git a/web/.gitkeep b/web/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web/.gitkeep @@ -0,0 +1 @@ +