Files
inkreach-official-website/AGENTS.md
T

14 KiB
Raw Permalink Blame History

AGENT.md - AI Agent 开发规范

开发流程

1. 梳理需求

使用 brainstorming 进行头脑风暴, 文档存放与命名规则如下:

需求类型 计划目录 命名规则 示例
新功能 plans/feature/ xxx-xxx-feature.md smart-view-feature.md
修 Bug plans/fix/ xxx-xxx-fix.md token-refresh-fix.md
重构 plans/refactor/ xxx-xxx-refactor.md api-split-refactor.md

使用 writing-plans 技能制定实施计划

开发新功能时必须评估权限需求:每个新功能/新操作都需要考虑是否需要纳入权限控制。具体评估方式见下方「权限系统」章节。

可参考的开发文档位于 docs/dev/*

2. 建立开发分支

确定好需求之后,就使用 enterprise-git-spec 技能来建立分支。

3. 按照需求开发

按照当前功能的计划文档的任务项及其任务细节来逐步实现功能, 全程严格地遵循技能 test-driven-development 进行 TDD 开发流程, 并遵循 executing-plans 技能来执行开发计划。

重要原则:所有测试必须通过

  • 开发过程中,必须确保所有测试用例都通过,包括新功能的测试和现有功能的测试
  • 如果发现现有测试失败,必须立即修复,确保新功能不会破坏旧功能
  • 只有在所有测试都通过的情况下,才能认为开发完成

所有任务完成后请遵循 verification-before-completion 技能完成验证

4. 合并到开发分支

所有测试通过后,使用 enterprise-git-spec 技能提交分支,然后合并回 develop 分支。

5. 沉淀开发经验

在实现功能过程中,将适用于任何项目的编码好想法、好思想、注意点等有助于项目推进的内容,及时追加到 AGENT.md 中。这些经验是跨功能、跨项目的通用知识,帮助后续开发少走弯路。

6. 更新项目结构文档

每次功能开发完成后,更新 docs/references/structs.md 文件。该文件记录整个项目的目录结构和每个模块的简要功能描述,便于每次迭代功能时快速理解整个项目全貌。

7. 更新使用文档

使用文档分为:

  1. README.md - 面向人类使用者,帮助其快速上手项目。仅在新功能开发完成后更新。内容保持简洁,聚焦于让用户快速跑通基础流程。
  2. docs/references/* - 面向人类使用者,提供项目的全面使用指南,支持深度探索模块与命令行细节。每次新功能开发完成或已有功能调整后必须更新。示例要丰富,帮助使用者理解各项功能的具体用法。
  3. skills/[项目名]/SKILL.md - 面向 LLM / AI Agent,指导大模型如何使用本项目。

快速开始文档每次新功能开发完成后才更新,具体更新 README.md 文件。确保文档包含新增功能的使用示例、命令说明和注意事项,帮助用户快速上手。

详细使用文档位于 docs/references/*,目录文件为 docs/references/index.md,请按照功能划分参考文档,并填充详细的使用说明,帮助用户深度探索模块/命令行的使用。每次新功能或旧功能调整了请更新最新的使用方法,例子应该丰富一些,便于使用者理解功能使用。

AGENT使用技能文档位于 skills/[项目名]/*,入口文件为 skills/[项目名]/SKILL.md,更新时机和要求与详细使用文档一致。

开发规范

代码优化

遵循 improve-codebase-architecture

类型规范

参考技能 typescript-advanced-types

测试规范

参考技能 javascript-testing-patterns

测试

每个任务目录应有对应的测试文件 test/sync/tasks/<task-name>/handler.test.ts

数据库设计

PostgreSQL 最佳设计实践: postgresql-table-design 技能 PostgreSQL 最佳性能调优实践: supabase-postgres-best-practices 技能 Prisma Postgres 最佳实践: prisma-postgres 技能

后端规范

参考 nestjs-best-practices 技能

你可以自己增加规范

经验沉淀(跨项目通用)

  • 入口 nginx 的真实挂载源在 v1 仓库:线上 official.inkreach.cc 的 nginx 容器由 /opt/inkreach/deploy 创建,挂载的是那边的 nginx/admin.confcertbot/acme 证书;v2 仓库 deploy/nginx/admin.conf 只是同步副本。改线上路由必须改 v1 的文件,再在该目录 docker compose up -d --force-recreate admin。v1/v2 目录同名 → compose 项目名相同 → pgdata/uploads 数据卷共享,重建不丢数据。
  • 文件型 bind mount 的 inode 陷阱:编辑器保存常替换 inode,容器内仍看到旧内容(:ro 挂载连 docker cp 都被拒);docker compose restart 也不会重新解析挂载。要让新文件内容生效只能 --force-recreate,新服务的挂载尽量挂目录而非单个文件。
  • 数据库漂移处理:连共享开发库时先跑 prisma migrate status;若报"列已存在"类错误,说明有人用 db push 带外改过库,用 prisma migrate resolve --applied <name> 把已存在的迁移标记为已应用,再 migrate deploy 应用真正缺的部分。切勿盲目 reset 共享库。
  • 连真实库的集成测试隔离:jest 并行套件共用一个数据库时,(a) 夹具的天然键(sdsCategoryId、名称等)必须带运行时间戳唯一化,禁止跨运行共享字面量;(b) 全量型操作(如 auto-group 扫全库)会顺带扫到其他并行套件的夹具,其写入路径必须对"成员中途消失"宽容(跳过而非抛错),否则会随机挂测试。
  • 跑全量 jest 前先停 dev servernest start --watch 等常驻进程与测试共用数据库时,其重编译窗口/后台钩子会与测试写入竞争,造成"单跑绿、全量偶发红"的假阳性;验证基线前先停掉所有 watch 进程再跑。
  • 中文断言勿手写字面量排序JS Array.sort() 对中文按 UTF-16 码位排(如 烫 U+70EB < 直 U+76F4),手写期望序列容易按拼音/习惯顺序写反;比较选项集合时用 expect.arrayContaining + 长度,或从同一排序函数生成期望。
  • pnpm 仓库容器化执行要挂仓库根pnpm 的 node_modules 是相对符号链接指向根 .pnpm store,容器里只挂子包目录(如 apps/api:/app)会断链报 "Cannot find module";必须挂整个仓库根并 -w 到子包。另外 Prisma 引擎与系统 libssl 版本强绑定:node:20-alpine 缺 libssl1.1 会报 engine 加载失败;仓库 .pnpm store 里生成的 client 是 openssl-1.1.x targetbookworm 系镜像(node:20-slim)同样跑不了,用 node:20-bullseye-slim 挂仓库根 + --network host(连本机一次性测试库)跑 jest/prisma 即可,无需依赖项目运行镜像。
  • 缓存值里绝不能带请求级切片(分页/字段裁剪):把 items.slice(page…) 的结果整个塞进缓存后,缓存键不含 page → 所有页码命中同一条目、页页返回第一页(total 对得上更具迷惑性);正确做法是缓存"全量物化结果",切片在缓存命中后按请求执行。TDD 用例必须包含"同键翻页 + 页内容随页码变化"的断言才能抓住这类错。
  • Prisma 唯一查询用字段名而非列名where: { id } 而非 @map("category_id") 映射后的 categoryIdschema @map 只影响 SQL 列名,Prisma Client 的唯一输入类型永远用 model 字段名。
  • 跨套件分页断言要圈定夹具:真实库上测"列表排序"时全库数据可能远超 pageSize,夹具根本进不了第一页;给夹具商品名加唯一前缀 + keyword 过滤圈定,断言既稳定又能看到完整顺序。
  • "绝对排序键 + 子集过滤"模式:需要"任意筛选组合下顺序都正确"时,给每条数据算好一组绝对排序键(如 国家→二级→款→priority,缺失沉底),筛选只做子集过滤不做特殊排序分支——比每个筛选组合写一套 orderBy 逻辑可靠得多。
  • "代表行选取收敛为单一方法":多端点共享同一实体视图(如族化商品对外的代表行)时,代表行选取规则必须收敛为一个私有方法供所有端点复用,禁止各端点各自 goods[0]——否则排序参数不同会导致 goodName/主图等字段在列表与详情间漂移。
  • "物化数组的顺序必须有确定性来源":把聚合结果物化进 JSONB(如 price_matrix 的 printCounts/crafts/logistics)时,"Set 去重保首现序"不是顺序保证——源查询没有 orderBy 时 Postgres 不承诺返回序,同一数据两次重算顺序可能漂移。必须:① 聚合后按业务词表序稳定排序(词表外自由文本沉底);② 源查询显式 orderBy 固定遍历序。测试用"打乱输入顺序断言输出全等"覆盖顺序确定性。
  • "新增维度取值 = 标签行 + 两处词表常量,缺一不可":工艺/物流/印花数量这类封闭维度新增可选值时,只往 tags 表插行不够——矩阵维度词表 DIM_VALUES 和展示序 OPTION_DISPLAY_ORDER 是硬编码常量,必须同步追加,否则打了新标签的链接会被词表过滤导致价格格子静默消失(比报错更危险)。同时确认自动派生规则(auto-tag-rules / admin origin-name)是否要认识新值;存量数据零影响的前提是"只放开准入,不主动打标"。
  • 测试夹具必须自包含:断言库内"存在某类数据"的用例(如标签组过滤)在全新/一次性数据库上必挂;夹具自己种下断言所依赖的数据,不依赖共享库的既有状态。
  • 严禁直接热修运行容器内的代码:本次线上 v2 镜像内被塞过未提交的词表改动(热转印),仓库重建镜像即复发且难排查;所有修复必须落在仓库并重建部署。排查"线上行为与代码不符"时先 md5sum 比对容器内源文件与仓库。
  • 两端"同构"解析器必须连测试用例也同构:admin 与 api 各有一份链接名解析器,本次展示 bug(品名(DTG180 SKU 显示成光款号)正是两端取括号策略不一致(api 首括号对 vs admin 末括号)所致。改任何一端解析行为时,另一端同样输入的用例必须同步补上(origin-name.spec ↔ origin-name.parser.spec/goods.service.spec)。
  • 共享开发库不可达时用一次性 docker postgres 跑集成测试docker run -d --name inkreach-test-pg -e POSTGRES_USER=test -e POSTGRES_PASSWORD=test -e POSTGRES_DB=inkreach_test -p 127.0.0.1:54329:5432 postgres:16-alpineDATABASE_URL=… npx prisma migrate deploy → jest/vitest 指向该库;用完 docker rm -f。夹具自包含的套件在新库上直接绿。
  • 宿主机即部署机时,改生产数据前先 docker inspect 拿容器真实注入的环境变量deploy/.env 里的密码可能与运行容器不一致(v2 栈独立 env);对两个栈的库做数据修复时,dry-run 清单必须逐栈分别核对后再 apply。
  • 改"镜像字段"的数据前先查覆盖路径:分类名每小时被 syncCategories 用 SDS 原名无条件覆盖——直接改库/界面改名都会被下一轮同步冲回。此类字段的清洗必须写进同步入库路径(如 cleanCategoryDisplayName),存量靠回填脚本;数据先改而镜像未重部署的窗口期内会被冲回一次,重部署后自动恢复。
  • 合并分叉血统时警惕"文本无冲突、行为有冲突":git 自动合并可能把两侧对同一机制的不同设计(如 热转印=烫画别名 vs 一等公民词表)拼进一个文件,编译通过但行为矛盾——合并后必须跑两侧血统各自的测试才能暴露;行级冲突反而不是最危险的。另:git status | head 截断会漏看冲突文件,连续 cherry-pick 后要全仓 grep '<<<<<<<' 扫一遍。
  • 生产栈收敛三件套:动栈结构前先 pg_dump -Fc 双库 + 数据卷归档 + 配置快照落 deploy/backups/<时间戳>/ 并写 RESTORE.md;切换用"外部卷 external 引用 + down 不带 -v + 切换前后行数 diff"保证数据零丢失;先 docker compose build 预构建再 down/up,把停机窗口压到秒级。
  • 矩阵维度占位不得借用业务词表既有值:曾让「不打印」链接的印花数量占位为「单面印花」,导致顾客端出现「不打印+单面印花」的自相矛盾组合(不打印根本无印花面)。2026-09-03 数据收口:光板/不打印链接不入族(family_id=NULL),矩阵不计算不打印工艺。回流风险organize/autoGroup 会把散链接按分类重新归族、人工改链接标签会触发 attachToMatchingFamily 回挂——跑这两类操作前必须先排查光板链接(清单与回滚见 deploy/backups/20260903-noprint-removal/)。
  • 重部署不会自愈物化 JSONprice_matrix 是物化列,代码修好/词表修正后已物化的矩阵不会自动重算(重算只在归族/成员变化/详情同步/标签调整等事件时触发)——族 148 曾因旧容器物化的坏矩阵跨镜像存活,"代码明明对了线上却没变"。此类修复收尾必须显式触发受影响族重算(可容器内 node -e 直调 FamilyRecomputeService.recomputeFamily,用已部署代码、免重建免鉴权)。
  • 批量数据修复前"全量 dump + 受影响行快照 + RESTORE.md"三件是底线:全量 pg_dump -Fc 兜灾难恢复,受影响行 CSV(含改前外键值)支持精准回滚,RESTORE.md 写清逐表恢复命令与重算步骤;事务内逐步核对影响行数与预期一致再 COMMIT。