From c43e6429957ad3cf9315a57008dc682bc95b76eb Mon Sep 17 00:00:00 2001 From: WuYongJie <549727955@qq.com> Date: Thu, 20 Aug 2026 19:12:33 +0800 Subject: [PATCH 1/2] chore: reserve AGENTS rules simplification -- 2.47.2 From 3047110b4ff412f9e05060a083dd0a1891de5dc0 Mon Sep 17 00:00:00 2001 From: WuYongJie <549727955@qq.com> Date: Thu, 20 Aug 2026 19:15:45 +0800 Subject: [PATCH 2/2] docs: simplify Codex team rules --- AGENTS.md | 231 ++++++++++++++---------------------------------------- 1 file changed, 60 insertions(+), 171 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 74021fb1..12cae321 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,190 +1,79 @@ -# CaiWuXiTong 团队通用规则 +# CaiWuXiTong 团队规则 -适用范围:本仓库所有成员、所有分支,以及使用 Codex 等 AI 编程工具完成的工作。 +本文件只保留团队协作和高风险操作的必要边界。普通功能开发应顺畅推进,不因生产级要求反复停下确认。详细步骤按任务需要读取对应 SOP,不在这里重复。 -## 1. 核心原则 +## 1. 工作原则与授权边界 -- 本项目是财务系统。金额、权限、审批、数据导入、数据库迁移和生产配置均属于高风险内容。 -- AI 是协作工具,不是审批人。AI 生成的代码、命令和结论必须由提交人检查并完成实际验证。 -- 不确定当前环境、分支、命令作用或数据范围时,停止操作并向负责人或 Codex 说明现场,不要猜。 -- 一次只完成一个明确任务;不顺手重构、升级依赖或修改无关模块。 +- 默认使用中文,先给结论;以当前代码、配置、数据和日志为准,旧文档和历史结论仅作参考。 +- 用户说“先看、排查、审计”时先只读说明事实和影响;用户说“修改、修复、实现”时,Codex 可直接完成范围内的本地改动、测试、提交和 PR,不必为正常开发步骤逐项请示。 +- 一次只处理一个明确任务,优先复用现有模式和解决根因;不顺手重构、升级依赖或修改无关模块。 +- 只有以下情况需要停止并说明:产品方向存在会改变结果的歧义;与其他任务发生实际写入冲突;需要生产发布、生产数据写入、迁移、删除或其他不可逆操作;缺少完成任务必需的外部权限。 +- 不为理论上可能、但正常使用无法触发的问题增加复杂框架、兜底层或重复检查。 -### 1.1 前端视觉规范 +## 2. 开工与多人协作 -- 仓库根目录 `DESIGN.md` 是本项目唯一正式视觉规范;`.impeccable/design.json` 是供 Codex、设计工具和自动检查读取的同源机器规范。所有前端任务在分析或修改代码前必须先完整阅读 `DESIGN.md`。 -- 项目正式主题固定为 VIP 黑金:最左侧工具轨道使用深黑,功能导航栏使用稍浅的黑;深色区域使用浅金或米白文字,浅色内容区使用黑色正文和深金交互色。旧有紫色、靛蓝色和高饱和亮蓝色不得继续作为主题色扩散。 -- 新增或修改页面必须复用全局设计令牌和共享组件,不得另写一套黑色、金色、字号、圆角、阴影或状态样式。成功、警告、错误、信息等语义色只用于对应状态,不得代替主题色。 -- 页面标题、侧边栏层级、图标、标签页、表格、滚动条、加载状态、选中状态和局部导航行为均按 `DESIGN.md` 执行;不得用整页刷新代替标签页或局部内容切换,也不得叠加两套选中标识。 -- 截图、浏览器批注和 `design-qa.md` 只属于验收证据或临时问题记录,不能覆盖正式视觉规范。需要改变视觉方向时,必须先得到项目负责人确认,并同步更新 `DESIGN.md` 与 `.impeccable/design.json`,再修改业务页面。 -- 前端 PR 必须说明是否符合 `DESIGN.md`、是否存在经批准的偏差,并用实际页面完成最小视觉与交互验证;“AI 已修改”或单看代码不能作为验收结果。 +- 开工先核对项目目录、`git status --short --branch`、`origin`、Git 身份和最新 `main`;保护现有未提交内容,不覆盖、不顺带提交。 +- 开发从最新 `main` 建立独立任务分支:功能用 `feature/用户名-任务名`,修复用 `fix/用户名-问题名`,紧急修复用 `hotfix/用户名-问题名`。 +- 只改独立页面、独立测试或文档时,不强制运行重型预检或提前建立 WIP PR;确认没有明显同名任务后即可开发。 +- 当任务会修改共享路由、Controller、Repository、数据表/视图、`source_key`、`scope`、权限名、菜单键或公共组件,或远程已有相同区域任务时,才运行 `scripts/codex-task-preflight.ps1`,列明“将修改”和“仅复用”内容,并尽早推送 WIP PR。 +- 只有双方会写同一契约或同一文件时才算冲突。仅调用现有路由、组件、Repository 或读取同一数据源不构成阻塞。 +- 多代理只用于边界清楚且不修改同一批文件的独立工作;主 Codex 负责最终复核。 -## 2. 分支与提交 +## 3. Git、PR 与合并 -- `main` 是稳定主线,禁止直接在其上开发、禁止强推。团队成员的任务必须先经过独立分支和 PR;任务 Codex 完成独立合并前自审及实际验证后,即被授权执行 Squash merge、推送 `main`、验证合并结果和清理任务分支,不需要等待其他开发者或项目负责人操作。 -- 每次开工必须先核对当前目录、远程仓库、Git 身份和当前分支:项目目录必须是 `CaiWuXiTong`,`origin` 必须指向 `WuYongJie/CaiWuXiTong`,分支用户名必须属于当前任务的实际开发者。发现其他项目名、其他项目开发者名或无法解释的旧分支时立即停止,不得继续提交。 -- 每项任务都必须从最新 `main` 新建分支;不得长期共用或复用旧任务分支。 -- 分支命名:新功能用 `feature/用户名-任务名`,修复用 `fix/用户名-问题名`,紧急修复用 `hotfix/用户名-问题名`。 -- 示例:`feature/dodo-login`、`fix/wangshu-amount-rounding`。 -- 一个分支只做一个任务。任务完成并合并后,删除本地和远程任务分支;任何人不得在已合并分支继续提交,下一项任务必须重新从最新 `main` 新建。 -- AI 开工前必须执行并核对 `git rev-parse --show-toplevel`、`git status --short --branch`、`git remote get-url origin` 和 `git config user.name`。分支名与实际任务负责人不一致时,AI 必须先报告现场,不得自行沿用该分支。 -- 提交前必须查看 `git status` 和 `git diff`,确认没有把别人的改动、日志、构建产物、`.env` 或敏感文件带进去。 -- 禁止使用 `git push --force`、`git reset --hard`、`git clean -fd`,除非负责人明确给出目标和操作步骤。 +- `main` 是稳定主线,不直接在其上开发,不强推。一个分支只完成一个任务。 +- 禁止使用 `git push --force`、`git reset --hard`、`git clean -fd`,除非负责人明确指定目标和操作。 +- 提交前检查 `git status`、实际 diff 和暂存区,只提交当前任务文件;不得带入 `.env`、凭据、日志、构建产物或他人的改动。 +- PR 说明做了什么、修改文件、验证结果,以及是否涉及金额、权限、数据库或配置。小型低风险任务不要求冗长模板说明。 +- 任务 Codex 在需求满足、相关测试通过且完整 diff 自审无误后,可直接执行 Squash merge、验证远程 `main` 并清理已合并分支,不需要另一位开发者或负责人再次操作。 +- 生产部署、生产迁移、数据修复、删除或覆盖配置仍需单独明确授权,不能因为代码已合并而自动执行。 -### 2.1 多人任务可见性与碰撞检查 +## 4. 验证要求 -- 团队按既有分工自行认领任务。每位开发者把已确定的任务交给自己的 Codex 后,Codex 必须先划定精确预计修改路径,并把路由、Controller、Repository、数据表/视图、上游 `source_key`、`scope`、权限名、菜单键等公共契约分为“将写入”和“仅复用、不修改”两类;范围不明确时不得开始修改。 -- 开工前由 Codex 执行 `scripts/codex-task-preflight.ps1`,检查最新 `main`、所有远程任务分支和主线既有实现。`-Contract`(或 `-WriteContract`)只能填写将写入的精确公共契约,`-ReuseContract` 填写只调用或依赖、明确不修改的公共契约;预计路径不得用 `app`、`tests`、`页面`、`接口`、`数据库`等宽泛根目录或词语代替。 -- 预检通过后立即创建并推送独立任务分支,并在 Gitea 创建标题以 `WIP:` 开头的 PR。WIP PR 必须在写大量代码前公开任务目标、模块边界和公共契约,不能等功能完成后才首次推送。 -- 只有预计修改路径重叠,或两个任务都会写入同一页面、路由、Controller、Repository、表/视图、`source_key`、`scope`、权限名、菜单键或公共组件时,Codex 才必须停止写入并报告具体重叠项。仅调用未修改的共享路由、`Pages::show()`、通用组件或既有 Repository 不属于冲突,但必须在 WIP PR 列为“仅复用”;如果实施中需要改该契约实现,必须先停止、更新 WIP PR 并重新预检。 -- 远程不可见的本机改动无法被其他 Codex 检查。任务分支和 WIP PR 不及时推送造成的重复开发,不能以“Codex 没发现”为理由继续合并。 -- 并行 Codex/Subagent 优先用于只读探索、测试、日志分析和代码审查;多个代理不得同时写同一批文件。需要并行写入时必须使用互不重叠的 worktree 和文件边界,由主任务代理统一复核。 -- 普通代码重叠和同步方案由相关分支提交人及其 Codex 处理。只有产品方向、重大业务规则或生产高风险操作需要升级确认。 +- 验证只覆盖本次改动最可能影响的真实路径,优先运行直接测试或实际页面;不因普通页面改动自动升级为全仓库、全服务审计。 +- 前端改动至少检查目标页面、关键交互和错误状态;后端改动至少运行相关测试或走一次目标接口;纯文档改动检查内容、链接和 diff 即可。 +- 涉及金额、权限、导入、审批或数据库结构时,增加对应边界和回归验证。 +- 已确认且状态未变化的内容不重复检查。未验证或验证失败时如实说明,不能写“应该没问题”。 +- 明确区分:本地已验证、已提交/推送、已合并、已上线和仍需生产验收。 -## 3. 新人使用 AI 的固定流程 +## 5. 前端与视觉 -新人本地接入的唯一手工动作是启动 Docker Desktop、在网页中登录,以及输入一次负责人提供的系统数据库密码。拉取代码、构建、初始化、本机引导库迁移、缓存清理、服务启动、页面打开、系统数据库切换后的两套上游验证和数据字典同步均由 Codex 完成;不得把命令、迁移、连接参数、TLS、证书、`APP_KEY` 或上游配置交给新人处理。 +- 只有前端任务需要先阅读根目录 `DESIGN.md`;`.impeccable/design.json` 是同源机器规范。 +- 正式主题为 VIP 黑金。新增或修改页面复用已有设计令牌和共享组件,不扩散旧紫色、亮蓝色或另一套黑金样式。 +- 标签页和局部导航使用局部切换,不用整页刷新代替;不叠加重复选中标识。 +- 截图和 `design-qa.md` 是验收证据,不覆盖 `DESIGN.md`。改变整体视觉方向需要负责人确认。 +- 前端验收以实际页面为准,不以代码截图或“已经构建”代替。 -1. 先确认任务目标和验收方式,由 Codex 根据现有代码、远程分支和团队既有分工划定影响范围与不能触碰的模块。 -2. 进入正确项目和分支,先执行 `git status`;看到陌生改动,先停止并说明情况。 -3. 向 AI 提供:任务目标、当前分支、报错或现象和验收结果;技术范围由 AI 检查后提出,不能反向要求新人猜文件、命令或数据链路。 -4. 要求 AI 运行任务预检,分别说明将写入与仅复用的公共契约、涉及文件、冲突风险和验证步骤;只有实际写入重叠时才阻断,预检阻断时先由相关开发者协调,不能继续修改。 -5. 预检通过后立即推送任务分支并创建 WIP PR,再进入正式开发。 -6. 修改后查看 diff,并要求 AI 用普通语言解释“改了什么、为什么、怎样测试”。 -7. 在本地或测试环境完成最小有效验证,记录实际结果。 -8. 更新 WIP PR 后,由当前任务的 Codex 切换到“合并前自审”阶段,重新从最新 `main` 审核完整 diff、公共契约、冲突、测试和风险;全部通过后安全合并到 `main`、验证主线并清理分支。新人不手工执行合并命令,也不得绕过 PR。 +## 6. 数据、上游与敏感信息 -推荐向 AI 提问的模板: +- 密码、Token、SSH 私钥、数据库连接串、真实财务数据和生产日志不得进入 Git、PR 或公开文档。 +- 需要长期保存的敏感信息写入被 Git 忽略的 `runtime/private/敏感信息.md`;写入前用 `git check-ignore` 确认。负责人明确要求时,可在当前一对一对话提供指定范围的敏感信息,但不得扩大传播。 +- 生产数据库写入、迁移、删除、批量导入和凭据轮换必须先说明影响,准备备份或回滚,并取得明确授权。普通本地只读排查和有限业务查询不需要额外审批。 +- `caiwu_system_config` 保存用户、权限、设置、连接资料、数据字典和同步状态;`caiwu_business_mirror` 保存项目已正式接入的上游业务数据。二者不是 SQL Server 网络代理。 +- 上游数据库统一按只读黑盒处理。业务查询使用固定、参数化的 Repository/查询执行器,禁止把用户输入拼成 SQL 或执行写操作。 +- 正式页面优先读取共享业务镜像;尚未迁移的旧页面可继续使用现有快照兼容层。接入新数据时沿用现有镜像数据集、稳定游标、断点同步和同步状态模式,不另造一套链路。 +- 两个现有来源固定为:`jiansun` 对应 `JianSun` 旧业务库;`operations_replica` 对应 `JSReportReplica` 的 `rpt` 只读视图。不得交换来源或写回历史临时库名。 +- 只有涉及上游接入、镜像同步、数据字典或生产刷新时,才读取 `docs/开发与部署SOP.md` 第 8 节及 `docs/上游业务镜像清单.md`。 -```text -项目:CaiWuXiTong(Laravel/PHP 财务系统)。 -任务:<要实现的功能或要修复的问题>。 -当前分支:<分支名>。 -现场:<报错、复现步骤、相关文件>。 -验收:<页面、接口或业务结果>。 -要求:先检查最新 main、全部远程任务分支和现有实现,运行 scripts/codex-task-preflight.ps1;明确列出精确修改路径、将写入的公共契约和仅复用但不修改的公共契约。只有实际写入重叠才停止并报告;仅复用共享路由或组件时记录在 WIP PR 后可继续。预检通过后立即推送任务分支并创建 WIP PR,再开始修改。不要执行删除、部署或生产数据库操作。 -``` +## 7. 新人本地开发 -## 4. PR 与合并 +- 新人只需要启动 Docker Desktop、在网页登录,以及输入一次负责人提供的系统数据库密码;拉取代码、初始化、缓存、容器和连接排错由 Codex 完成。 +- 标准初始化由 Codex 在最新 `main` 上运行不带参数的 `deploy/local-init.sh`。不要让新人判断 `--build`、手工迁移共享数据库、复制他人 `.env` 或配置上游连接。 +- 本地连接系统数据库后,用户、菜单、设置和上游登记继续使用团队系统数据库,不把主连接切回本机临时 MySQL。 +- 与数据库无关的普通页面或业务功能可以直接开发,不要求开发者先理解或验证全部上游、镜像和生产部署链路。 +- 只有接入新上游数据时,才需要验证对应来源的只读查询、镜像同步状态、总数及代表性分页/筛选;无需每个普通任务重复验证两套数据库。 -- 所有成员的任务分支必须通过 PR 合并到 `main`。PR 满足检查和验证条件后,任务开发者的 Codex 可以直接执行 Squash merge,不需要项目负责人代为合并;禁止绕过 PR 把开发提交直接推入 `main`。 -- PR 作者必须填写:做了什么、Codex 改了哪些文件、怎样测试、是否涉及金额/权限/数据库/配置。 -- WIP PR 是任务占用和公共契约的远程可见记录。标题使用 `WIP: <任务>`;描述必须使用仓库的 `.gitea/PULL_REQUEST_TEMPLATE.md`,其中预计范围、将写入契约和仅复用契约在开工时填写,实际范围和测试结果在 Codex 合并前自审时补齐。 -- PR 不要求另一位开发者审核。任务 Codex 必须在实现结束后另做一次合并前自审:重新读取需求和验收标准,以 `origin/main...任务分支` 的完整 diff 为准逐文件检查,不得直接沿用开发阶段的“已经完成”结论。 -- 涉及金额计算、权限、导入、数据库迁移、账户或系统配置时,必须在 PR 中明确标注影响与回滚;代码仍可在检查和测试通过后由 Codex 合并,但生产迁移、数据修复、删除、覆盖配置和部署继续执行独立高风险授权。 -- 使用仓库默认的 Squash merge(压缩合并)。执行合并的 Codex 必须先重新拉取远程引用,确认工作区干净、PR 不再是 WIP、需求和验收逐项满足、完整 diff 无越界或敏感内容、测试通过、目标为最新 `main` 且没有未协调重叠,再执行合并。 -- 合并后 Codex 必须核对远程 `main` 已包含目标改动,报告合并提交和验证结果,并删除已合并的本地、远程任务分支;下一项任务必须重新从最新 `main` 创建分支。 +## 8. 构建与生产部署 -## 5. 测试与问题处理 +- 只有用户明确要求“部署、上线”时才执行生产发布;正式发布只使用已合并的最新 `main`。 +- Windows 开发机统一使用 `scripts/deploy-from-workstation.ps1`。服务器只运行开发机已构建的 `caiwu_akaunting:` 镜像,禁止在服务器执行 Composer、npm 或 Docker 构建。 +- 当前生产入口为 `https://218.93.190.75:8442`;未完成正式域名或公网 `80/443` 验收前,不改成无端口地址,也不在日常发布使用 `-ConfigureHttps`。 +- 发布脚本检测到新增数据库迁移时必须停止,取得负责人明确授权并完成备份后才能使用迁移开关。 +- 容器内 Laravel 命令使用 `www-data`。发布后只需确认部署 SHA、应用容器健康、受影响的真实页面/接口、迁移是否执行,以及当前和上一版镜像可回滚。 +- 程序静态资源随应用镜像同源发布;七牛只存用户上传的业务图片、票据和附件。 +- 只有本地初始化、服务器维护、生产发布或数据库迁移任务需要读取 `docs/开发与部署SOP.md` 的对应章节;普通功能开发无需加载整份 SOP。 -- 修改完成不等于可用。至少验证正常流程、错误输入/无权限场景和本次改动影响的旧功能。 -- 出现冲突、测试失败或 PR 显示落后 `main` 时,不要自行猜命令。先让 AI 只分析同步方案,禁止强推和 rebase;普通代码冲突交由相关分支提交人及其 Codex 处理,未解决前不得合并。 -- 提交问题时必须写清:环境、账号角色、复现步骤、实际结果、期望结果和报错截图/日志(脱敏后)。 +## 9. 规则优先级 -## 6. 数据与安全红线 - -- 不得提交 `.env`、密码、Token、SSH 私钥、数据库连接串、真实财务数据、客户数据或生产日志。 -- 项目负责人明确要求时,可以在当前一对一 AI 对话中直接发送其指定的密码或连接信息;只发送完成当前任务所需的范围,不得自动扩散到工单、PR、聊天群、公开摘要或无关日志。 -- 本项目使用本地私有文档 `runtime/private/敏感信息.md` 记录需要长期保留的密码、Token、服务器和数据库连接等敏感信息。整个 `runtime/` 已被 `.gitignore` 排除;写入前和提交前必须用 `git check-ignore runtime/private/敏感信息.md` 以及暂存区检查确认它不会进入 Git,禁止使用 `git add -f` 强制添加。 -- 不得在不确认环境和影响范围时执行数据库写入、迁移、删除、导入、部署或服务器命令。 -- 任何包含金额、账户、登录凭据、权限或数据库连接的信息都按敏感数据处理。 -- 发现误提交、泄露或错误操作,立即告知负责人;不要自行删除记录掩盖问题。 - -## 7. 本仓库的最小验证要求 - -- 前端改动:至少检查目标页面、正常交互和错误提示。 -- 后端改动:至少执行相关测试或启动后走一次目标接口/页面。 -- 数据库迁移:新人不得自行在共享环境执行;先在 PR 说明影响、验证方式和回滚思路。 -- 未完成验证时,PR 必须明确写“未验证”及原因,不能写“应该没问题”。 - -## 8. 固定构建与部署规则 - -### 8.1 职责边界 - -- 项目负责人只负责产品方向、验收标准和高风险授权,不负责日常构建、上传、部署命令和服务器维护操作。 -- 新人负责描述任务、检查结果和发起 PR;Codex 负责按本节流程完成环境检查、构建、部署、验证和收口,不得把一串命令丢给项目负责人执行。 -- 正式发布只允许使用已合并的 `main`。非 `main` 只能用于明确授权的测试发布。 -- 生产数据库迁移、数据修复、删除、覆盖配置等高风险动作,仍需项目负责人明确授权。 - -### 8.2 服务器红线 - -- 当前生产服务器约有 16GB 内存,仍只负责运行容器、健康检查和镜像切换。 -- 严禁在服务器执行 `docker build`、`docker compose build`、`npm install`、`npm run production`、`composer install` 或其他源码构建命令。 -- `compose.jiangling.yml` 不得出现 `build:`;服务器只能运行开发机已经构建并上传的 `caiwu_akaunting:` 镜像。 -- 当前生产直连地址固定为 `https://218.93.190.75:8442`;宿主机 Nginx 监听 `8442`,应用容器仅绑定 `127.0.0.1:18088`。在云平台真正放行 `80/443` 并完成受信任证书验收前,不得把发布脚本或 `APP_URL` 改回不带端口的地址。 -- 当前 `8442` 使用服务器内部证书,浏览器可能显示证书警告。待 `80/443` 真正可用或正式域名完成解析后,再通过 `-ConfigureHttps` 切换到受信任证书和不带端口的正式入口;证书、私钥和 ACME 账户不得进入 Git 或应用镜像。 -- `mariadb:11.4` 运行镜像由开发机缓存并仅随首次初始化全量包上传,服务器不得在发布时临时访问 Docker Hub。 -- 日常发布必须通过只监听 `127.0.0.1` 的服务器本机 Registry 和 SSH 隧道传输,仅上传 Registry 中不存在的镜像层;禁止每次上传完整 `docker save` 压缩包。 -- 日常增量包必须由 BuildKit 直接导出 OCI 分层格式;禁止用 `docker save` 作为日常增量源,因为其未压缩层在重复导入时会产生不同压缩摘要、破坏跨版本层复用。 -- 服务器保留当前镜像和上一个可回滚镜像,其他本项目旧镜像在发布成功后清理。 -- 服务器发布必须使用互斥锁;同一时间只允许一个人切换版本,禁止并发覆盖。 - -### 8.3 开发机固定流程 - -- Windows 开发机统一使用 `scripts/deploy-from-workstation.ps1`,不得手工拼接构建、打包、上传和启动命令。 -- 镜像标签使用 Git 提交 SHA;工作区有未提交的受控文件时,脚本必须拒绝发布。 -- 使用项目专属 BuildKit 构建器 `caiwu-builder`。禁止日常使用 `--no-cache`、`--pull` 或删除全部 Docker 数据。 -- Dockerfile 必须先复制锁文件再安装依赖:只有 `composer.lock`、`package-lock.json` 或基础镜像定义变化时,才允许对应依赖层失效。 -- 前端资源必须由开发机宿主系统运行 `scripts/build-frontend.ps1` 构建;脚本固定并复用项目专用 Node 20,不得在 Docker 虚拟机或服务器内执行前端打包。 -- JavaScript、CSS、字体、PWA 图标和其他程序静态资源必须随应用镜像发布并由应用同源提供,禁止上传到七牛或把对象存储失败作为程序发布前置条件。七牛只用于用户上传的业务图片、票据和附件。 -- 基础镜像、Composer 下载缓存、npm 下载缓存和未变化的构建层应直接复用,不得每次全量下载。 -- `-BootstrapServer` 仅用于新服务器首次全量初始化;已有服务器的日常发布自动走增量镜像层传输。 -- `-ConfigureHttps` 仅在公网 `80/443` 已真实放行后用于首次配置或修复宿主机 Nginx、IP 证书和自动续期;当前 `8442` 入口的日常发布不得添加。 - -### 8.4 磁盘和缓存上限 - -- Docker Desktop 虚拟磁盘上限建议设为 60GB;宿主机至少保留 15GB 可用空间。前端打包使用宿主机内存,不要求为了本项目调高 Docker 虚拟机内存。 -- 发布脚本使用独立缓存并将 BuildKit 缓存控制在 3GB 内,只清理 7 天前的本项目缓存。 -- 前端 Node 堆内存默认上限为 4GB,JavaScript 压缩默认最多使用 2 个工作线程;不得为了追求构建速度取消限制。 -- `package-lock.json` 和 Node 版本未变化时复用 `node_modules`;页面模板变化只重建 Tailwind CSS,只有 JavaScript 源码或依赖变化才重新打包 JavaScript。 -- 开发机、服务器 Docker 和服务器本机 Registry 默认各保留 2 个本项目版本;上传用临时 `image.tar` 无论成功失败都必须删除。 -- 禁止脚本自动执行全局 `docker system prune -a`、删除其他项目镜像、删除卷或重置 Docker Desktop。 -- Docker 虚拟磁盘文件不会因为普通清理立即缩小;日常目标是控制已用空间不再增长,不得让新人自行删除或重建虚拟磁盘。 - -### 8.5 发布安全与验收 - -- SSH 私钥、`runtime/.env`、镜像临时包、数据库密码不得进入 Git 或 Docker 构建上下文。 -- 首次服务器初始化由脚本生成数据库密码和 `APP_KEY`,默认只写入服务器私有运行配置和本地 `runtime/private/敏感信息.md`。项目负责人明确要求时可以在当前一对一 AI 对话中提供指定值;不得进入 Git、PR、工单、群聊、公开文档或持久化日志。 -- 数据库迁移默认关闭;检测到新增迁移时发布必须停止,获得负责人授权后才可显式开启。 -- 新镜像必须先通过本机后端健康检查,再通过公网 HTTPS 页面验收;失败时自动恢复上一个镜像,并保留日志用于排查。 -- 生产业务文件统一使用项目唯一的私有七牛桶,固定逻辑盘名为 `uploads`;Access Key 和 Secret Key 只允许存在发布机用户环境、被 Git 忽略的 `runtime/qiniu-business-storage.env` 或服务器 `runtime/qiniu-storage.env`。发布脚本负责首次安全写入服务器私有配置,激活脚本负责读写探测和旧本机上传文件的幂等复制,原件保留用于回滚。新人不得配置对象存储。 -- 私有业务图片经应用完成用户、公司和附件权限检查后,才生成短期签名地址;程序脚本、样式和字体不得使用该签名域名。 -- 发布完成必须报告:分支、提交 SHA、镜像标签、服务器容器状态、真实页面结果、是否执行迁移、清理结果。 -- 容器内所有 `php artisan`、初始化、测试和后台刷新命令必须以 `www-data` 运行;手工命令统一使用 `docker compose exec -u www-data ...` 或 `docker exec -u www-data ...`。禁止默认 `root` 执行后在 `storage`、`bootstrap/cache` 或 `.env` 留下网页进程不可写的文件。入口脚本启动时必须修复旧属主,`app:ready` 必须以 `www-data` 验证数据库连接和运行目录写权限,不得把角色或权限映射作为容器健康条件。 - -### 8.6 上游数据库读取规则 - -- 本系统按 3 个以上上游来源设计;来源统一登记在 `config/upstreams.php`,每个来源必须拥有独立配置、适配器、缓存命名空间、并发预算、熔断状态和后台刷新任务。一个来源故障不得清空或阻塞其他来源的快照。 -- 上游是长期运行且不可修改的旧系统,统一按只读黑盒处理;不得要求修改其账号、表结构、索引、字段或启用 Change Tracking 等功能。 -- 本地开发环境(`APP_ENV=local`)直接执行 `UpstreamQueryCache` resolver 中已经写入代码的只读查询,不等待生产刷新节点、共享快照或 `allowed_scopes`。两套连接资料仍从共享系统数据库自动解析,开发者只填写一次系统数据库密码,不再配置上游环境变量。 -- 项目正式使用到的上游表或视图,必须逐项物化到独立逻辑库 `caiwu_business_mirror`。页面查询、分页、筛选和汇总优先读取该共享业务镜像,不得再按页码或筛选条件临时生成一页查询快照。`caiwu_system_config` 只保存用户、权限、系统设置、连接资料、数据字典和同步状态;两个逻辑库默认复用同一台 MariaDB、同一套 TLS 和团队密码,新人仍只输入一次系统数据库密码。 -- 现有尚未迁移的页面可以暂时继续使用 `UpstreamQueryCache`,但这是过渡兼容方案。新增业务表接入和已出现分页缺页、冷查询等待问题的旧页面,必须同时实现上游固定 Repository、稳定批次游标、镜像表、断点同步、同步状态和只读镜像 Repository;不得继续扩展按参数快照。 -- 两套上游的表、视图和字段结构由命令 `upstream:schema:sync` 低频读取 `INFORMATION_SCHEMA`,保存到共享系统数据库 `upstream_schema_columns`。任何能够直连的开发环境或生产刷新节点都可以生成目录;同步失败必须保留最近一次完整目录。 -- 缺少现成 Repository、页面适配器、生产 `scope` 或共享快照,不代表本地开发无法读取该来源。开发者和 Codex 在 `APP_ENV=local` 中可以直接通过 `UpstreamReadOnlyQueryFactory::forSource()` 对数据字典中选定的对象执行少量、限定字段和返回量的只读 `SELECT/WITH`,用于确认业务行、理解字段并实现功能;不需要先修改云数据库记录或等待生产刷新。禁止把用户输入拼成 SQL、输出敏感业务行或以此替代合并前的正式 Repository/测试。 -- 新来源适配器必须通过 `UpstreamReadOnlyQuery` 执行固定、参数化的只读查询,禁止把原始 PDO 连接暴露给控制器或页面。即使现有数据库账号本身有写权限,应用代码也不得执行写入、高风险语句或存储过程。 -- 系统数据库只保存活跃查询登记、参数、访问范围和共享结果,不执行 SQL。禁止把任意 SQL、DSN 或凭据写入任务表让后台解释执行;生产后台进程只能运行已经合并到 `main` 并在 `UpstreamSnapshotRefresher` 中登记的固定查询代码。 -- 开发者需要尚未缓存的新表或字段时,必须在任务说明和 PR 中列出来源标识、业务目的、表/视图、字段、筛选与排序、最大返回量、公司/权限范围、缓存时间和失败表现;未说明边界的“把整张表接进来”不得合并。 -- 新业务表在任务分支中必须同时完成 Repository/适配器、稳定批次游标、镜像表、同步状态、可断点续跑的同步器、只读镜像 Repository、页面切换和测试。自动测试使用脱敏 fixture 或测试替身;能够直连的开发机可执行少量真实只读验收,但不得输出凭据、敏感业务行或提交本机覆盖配置。 -- 本地探索可以直接读取上游验证字段和业务含义;正式页面完成接入后,本地和生产都优先读取共享业务镜像。首次全量同步完成前必须明确显示“尚未完成同步”,不得把局部数据或空表显示成真实的“无数据”。 -- 快照复用按“来源 + 数据范围 + 查询条件 + 公司/权限范围”判断,与账户数量和开发机数量无关;权限或数据范围不同的结果不得错误共用。 -- 生产列表和汇总快照默认 2 分钟,选项类数据默认 60 分钟。生产页面命中过期快照时立即返回共享旧值并排入后台刷新。 -- 生产相同查询使用共享系统数据库中的独立单飞锁;每个来源的不同冷查询默认最多占用 2 个上游槽位、每分钟最多 6 个查询组、每轮最多刷新 2 个近期活跃查询。上述限制不作用于本地开发直连。 -- 生产刷新必须设置连接超时、查询超时、慢查询冷却和连接失败熔断;本地开发直连只保留连接与查询超时,错误立即脱敏返回,不进入共享冷却。 -- 上游 API 必须保留 `X-Caiwu-Data-Status` 和 `X-Caiwu-Data-Synced-At` 响应头;验收同时检查数据状态和同步时间,不能只看 HTTP 200。 -- 每个来源的连接开关统一保存在系统数据库。`allowed_scopes` 只控制生产快照刷新,不阻挡本地开发直连;生产范围仍需使用精确前缀,禁止用 `*` 放开核心大表。 -- 跨来源报表不得在页面请求中实时连接多个上游做 JOIN;需要组合的数据先分别受控读取并物化到共享标准表或查询快照,再从共享数据生成报表。物化记录必须保留来源标识、上游业务键和同步时间,金额仍以本地财务规则校验。 -- 共享业务镜像是项目实际使用表的受控副本,不是上游全库复制。每张表必须优先使用可靠的更新时间、完成时间或递增业务键做小批量增量同步;没有可靠变更标记时,只允许经评估的重叠时间窗、低频分段核对或定向补偿,禁止每分钟全表扫描。 -- 首次全量历史数据同步必须单独评估行数、时间窗口和上游低峰期,不得在日常发布时自动执行。 -- 生产服务器不能直接访问某个上游时,只允许通过专用低权限 SSH 账户建立受限反向隧道;每个来源使用独立 `SourceKey`、私有配置、计划任务和 Docker 私网端口,禁止监听公网地址,隧道账户禁止 Shell、TTY、本地转发和任意端口转发。 -- 隧道由 `scripts/keep-upstream-tunnel.ps1` 自动重连,并通过 `scripts/install-upstream-tunnel-task.ps1 -SourceKey <来源标识>` 安装。数据库凭据不得作为隧道参数;每台候选中继开发机使用独立 SSH 私钥,不得多人共享私钥。 -- 每个来源最多安排 1 台主中继和 1 台备用中继;同一来源同一时刻只允许一个远端监听成功,备用机低频重试。隧道中断时页面继续读取该来源旧快照,禁止绕过缓存直接重试上游。 -- 系统数据库的启动连接只允许存在于服务器私有 `runtime/.env`;超级管理员和普通管理员可在“数据库管理”中连接。新人接入只验证密码能够解锁固定资料、数据库能够连接、TLS 已自动建立且基础系统表存在,并在持久化 `storage` 中生成私有备份。迁移版本、管理员权限映射、公司映射和云数据库配置不再作为切换前置条件;`super_admin` 和 `admin` 角色不受缺失的权限关联表记录阻塞。 -- 云数据库连接与系统数据库配置必须分开。显式开启 `UPSTREAM_STORED_CONFIG_ENABLED` 后,云数据库密码在 `system_database_connections` 中同时保留旧版 `APP_KEY` 密文用于紧急回滚,并使用系统数据库登录密码派生的密钥写入 `shared_password` 供受信任开发机共享;真实值仍不得进入代码、提交、PR、共享文档或日志。系统数据库固定主机、端口、库名和账号以密文团队资料保存在代码中,不含数据库密码;新人页面只允许填写系统数据库密码,由它解锁固定资料并自动启用 TLS。禁止恢复主机、端口、账号、TLS、证书或 CA 路径等新人表单。系统数据库密码轮换前必须先完成共享云数据库密文重加密、数据库备份和团队连接资料密文更新。只有隔离排错或尚未迁移的旧环境才允许显式开启本机覆盖,并通过私有 `DB_<来源>_*` 环境变量提供完整连接。中继开发机只保留已收紧 ACL 的隧道端点配置,不保存数据库密码。 -- 本地开发的标准入口只有“系统设置 → 数据库管理 → 系统数据库”。开发者只填写并验证同一套系统数据库密码,其他连接参数由项目自动设置;成功后系统用户、侧边栏、系统设置和云数据库登记必须继续使用该系统数据库。不得再把主业务连接的 `DB_HOST` 改回本机 MySQL 容器,否则会形成一套互不相干的本地数据,导致用户、配置、来源映射和业务结果与团队不一致。 -- 两个现有来源的标识和数据库映射固定为:`jiansun` 对应 `JianSun` 旧业务库,`operations_replica` 对应 `JSReportReplica` 的 `rpt` 只读视图。不得把 `shujuku`、本机测试库名或历史截图中的临时名称写回共享记录,也不得交换两个来源的账号或数据库名。 -- 开发者拉取包含本规则的最新代码后,由 Codex 运行不带参数的 `deploy/local-init.sh`。脚本根据 Dockerfile、依赖锁文件、前端源码和静态资源计算镜像指纹,构建输入变化或必要静态资源缺失时自动重建,并清除 Laravel 配置缓存;不得要求新人判断是否使用 `--build`。`docker-compose.local.yml` 必须继续挂载 `./modules:/var/www/html/modules`,禁止只重启旧镜像后根据旧模块或旧静态资源判断主线无效。 -- 本机临时引导库的新增迁移由 `deploy/local-init.sh` 和新版容器入口自动补齐;该逻辑只允许在 `SYSTEM_DATABASE_MODE=bootstrap`、MySQL 驱动且主机为固定容器服务名 `mysql` 时运行。连接共享系统数据库后必须自动跳过,普通开发者不需要也不得自行执行 `php artisan migrate`;看到本机迁移 `Pending` 时应重新运行标准初始化脚本,而不是操作共享数据库。 -- Codex 排查开发机连接时,必须先确认当前主业务库仍是共享系统数据库,再确认 `UPSTREAM_STORED_CONFIG_ENABLED=true`、`UPSTREAM_LOCAL_CONFIG_ENABLED=false`,随后通过 `UpstreamSourceRegistry` 验证完整连接来自 `system_database_connections`。不得通过填写本机 `DB_JIANSUN_*`、`DB_OPERATIONS_REPLICA_*`、复制他人 `.env` 或统一 `APP_KEY` 来掩盖共享配置读取错误。 -- 系统数据库 `caiwu_system_config` 保存应用数据、云数据库配置、上游数据字典和同步状态;共享业务库 `caiwu_business_mirror` 保存已正式接入的上游业务行。二者都不是 SQL Server 网络代理。开发者只连接一次团队数据库,程序自动复用同一主机、端口、账号、密码和 TLS 访问两个逻辑库;需要探索尚未接入的数据时,Codex 才使用系统数据库中的连接资料执行受限只读上游查询。 -- 开发验收必须在不复用负责人现有 `.env`、登录会话、容器或数据库卷的全新隔离环境中完成:只填写一次系统数据库密码,确认两个共享逻辑库均可读,再分别验证两套来源的共享配置解析、`SELECT 1` 和至少一个真实业务表/视图的只读查询。正式接入的数据还必须验证镜像总行数、第二页或末页、筛选结果、最近同步时间和上游限定计数能够对账。只在负责人已配置环境中测试不算新人接入验收。连接资料由程序自动读取和使用,不让新人手工配置;上游 Repository 仍必须通过 `UpstreamReadOnlyQuery` 执行固定、参数化的 `SELECT`,禁止写操作和任意 SQL 输入。 - -详细 SOP 见 `docs/开发与部署SOP.md`。 +- 本文件是团队当前有效的简明规则。`DESIGN.md` 和 `docs/开发与部署SOP.md` 只在对应任务中按需读取。 +- 详细文档与本文件冲突时,以本文件和负责人最新明确要求为准;历史截图、旧聊天记录和临时排错方案不能覆盖当前规则。 -- 2.47.2