# CaiWuXiTong 团队通用规则 适用范围:本仓库所有成员、所有分支,以及使用 Codex 等 AI 编程工具完成的工作。 ## 1. 核心原则 - 本项目是财务系统。金额、权限、审批、数据导入、数据库迁移和生产配置均属于高风险内容。 - AI 是协作工具,不是审批人。AI 生成的代码、命令和结论必须由提交人检查并完成实际验证。 - 不确定当前环境、分支、命令作用或数据范围时,停止操作并向负责人或 Codex 说明现场,不要猜。 - 一次只完成一个明确任务;不顺手重构、升级依赖或修改无关模块。 ## 2. 分支与提交 - `main` 是稳定主线,默认禁止直接推送、禁止强推、禁止直接修改。项目负责人 `WuYongJie`,以及得到其明确授权的 Codex,可以直接合并 PR 或直接推送 `main`;任何身份仍禁止强推。 - 每项任务都必须从最新 `main` 新建分支;不得长期共用或复用旧任务分支。 - 分支命名:新功能用 `feature/用户名-任务名`,修复用 `fix/用户名-问题名`,紧急修复用 `hotfix/用户名-问题名`。 - 示例:`feature/dodo-login`、`fix/wangshu-amount-rounding`。 - 一个分支只做一个任务。任务完成并合并后,删除该分支;下一项任务重新从 `main` 新建。 - 提交前必须查看 `git status` 和 `git diff`,确认没有把别人的改动、日志、构建产物、`.env` 或敏感文件带进去。 - 禁止使用 `git push --force`、`git reset --hard`、`git clean -fd`,除非负责人明确给出目标和操作步骤。 ## 3. 新人使用 AI 的固定流程 1. 先确认任务目标、验收方式、影响范围和不能触碰的模块。 2. 进入正确项目和分支,先执行 `git status`;看到陌生改动,先停止并说明情况。 3. 向 AI 提供:任务目标、当前分支、报错或现象、相关文件、不可修改的范围。 4. 要求 AI 先说明改动计划、涉及文件、风险和验证步骤;确认后再修改。 5. 修改后查看 diff,并要求 AI 用普通语言解释“改了什么、为什么、怎样测试”。 6. 在本地或测试环境完成最小有效验证,记录实际结果。 7. 推送任务分支并发起 PR;新人不得自行绕过 PR 合并到 `main`。项目负责人和其明确授权的 Codex 按上面的例外执行。 推荐向 AI 提问的模板: ```text 项目:CaiWuXiTong(Laravel/PHP 财务系统)。 任务:<要实现的功能或要修复的问题>。 当前分支:<分支名>。 现场:<报错、复现步骤、相关文件>。 边界:不要修改 <模块/表/配置>;不要执行删除、部署、生产数据库操作。 要求:先列出改动计划、风险和验证步骤,等我确认后再改。 ``` ## 4. PR 与合并 - 新人和普通协作者的任务分支必须通过 PR 合并到 `main`;项目负责人和其明确授权的 Codex 可以作为例外直接合并或推送。 - PR 作者必须填写:做了什么、Codex 改了哪些文件、怎样测试、是否涉及金额/权限/数据库/配置。 - 新人提交的 PR 至少由另一位成员检查后才能批准;作者不得把“AI 已完成”当作测试结果。项目负责人和其明确授权的 Codex 不受这条审核人数限制,但仍必须完成实际验证并如实记录结果。 - 涉及金额计算、权限、导入、数据库迁移、账户或系统配置时,必须在 PR 中明确标注,并由负责人最终确认。 - 使用仓库默认的 Squash merge(压缩合并)。合并由负责人或指定合并人执行。 - PR 合并后分支自动删除;不要把已合并分支继续用于新任务。 ## 5. 测试与问题处理 - 修改完成不等于可用。至少验证正常流程、错误输入/无权限场景和本次改动影响的旧功能。 - 出现冲突、测试失败或 PR 显示落后 `main` 时,不要自行猜命令。先让 AI 只分析同步方案,禁止强推和 rebase;必要时找负责人处理。 - 提交问题时必须写清:环境、账号角色、复现步骤、实际结果、期望结果和报错截图/日志(脱敏后)。 ## 6. 数据与安全红线 - 不得提交 `.env`、密码、Token、SSH 私钥、数据库连接串、真实财务数据、客户数据或生产日志。 - 不得把上述内容粘贴到 AI 对话、工单、PR、聊天群或截图中。 - 不得在不确认环境和影响范围时执行数据库写入、迁移、删除、导入、部署或服务器命令。 - 任何包含金额、账户、登录凭据、权限或数据库连接的信息都按敏感数据处理。 - 发现误提交、泄露或错误操作,立即告知负责人;不要自行删除记录掩盖问题。 ## 7. 本仓库的最小验证要求 - 前端改动:至少检查目标页面、正常交互和错误提示。 - 后端改动:至少执行相关测试或启动后走一次目标接口/页面。 - 数据库迁移:新人不得自行在共享环境执行;先在 PR 说明影响、验证方式和回滚思路。 - 未完成验证时,PR 必须明确写“未验证”及原因,不能写“应该没问题”。 ## 8. 固定构建与部署规则 ### 8.1 职责边界 - 项目负责人只负责产品方向、验收标准和高风险授权,不负责日常构建、上传、部署命令和服务器维护操作。 - 新人负责描述任务、检查结果和发起 PR;Codex 负责按本节流程完成环境检查、构建、部署、验证和收口,不得把一串命令丢给项目负责人执行。 - 正式发布只允许使用已合并的 `main`。非 `main` 只能用于明确授权的测试发布。 - 生产数据库迁移、数据修复、删除、覆盖配置等高风险动作,仍需项目负责人明确授权。 ### 8.2 服务器红线 - 当前服务器只有 2GB 内存,只负责运行容器、健康检查和镜像切换。 - 严禁在服务器执行 `docker build`、`docker compose build`、`npm install`、`npm run production`、`composer install` 或其他源码构建命令。 - `compose.jiangling.yml` 不得出现 `build:`;服务器只能运行开发机已经构建并上传的 `caiwu_akaunting:` 镜像。 - 生产访问地址固定为 `https://118.196.84.79`(不附加端口);宿主机 Nginx 监听 `80/443`,HTTP 自动跳转 HTTPS,应用容器仅绑定 `127.0.0.1:18088`。 - HTTPS 使用 Let’s Encrypt 短期 IP 证书,服务器定时器每 8 小时检查续期;证书、私钥和 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 虚拟机或服务器内执行前端打包。 - 基础镜像、Composer 下载缓存、npm 下载缓存和未变化的构建层应直接复用,不得每次全量下载。 - `-BootstrapServer` 仅用于新服务器首次全量初始化;已有服务器的日常发布自动走增量镜像层传输。 - `-ConfigureHttps` 仅用于首次配置或修复宿主机 Nginx、IP 证书和自动续期;日常发布不得重复添加。 ### 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`,不在终端、聊天或文档中输出。 - 数据库迁移默认关闭;检测到新增迁移时发布必须停止,获得负责人授权后才可显式开启。 - 新镜像必须先通过本机后端健康检查,再通过公网 HTTPS 页面验收;失败时自动恢复上一个镜像,并保留日志用于排查。 - 发布完成必须报告:分支、提交 SHA、镜像标签、服务器容器状态、真实页面结果、是否执行迁移、清理结果。 ### 8.6 上游数据库读取规则 - 上游是长期运行且不可修改的旧系统,按只读黑盒处理;不得要求修改其账号、表结构、索引、字段或启用 Change Tracking 等功能。 - 业务页面禁止直接、无缓存地查询上游数据库;统一通过 `JianSunQueryCache` 读取持久化在本机 `storage` 卷中的活跃查询快照。 - 快照复用按“数据范围 + 查询条件”判断,与账户数量无关;权限或数据范围不同的结果不得错误共用。 - 列表和汇总快照默认 2 分钟,选项类数据默认 60 分钟。页面命中过期快照时立即返回本地值并排入后台刷新,不得等待上游,也不得通过前端高频轮询制造压力。 - 相同查询使用独立单飞锁;不同冷查询最多占用 2 个上游槽位。每分钟最多 6 个查询组,每分钟后台最多刷新 2 个近期活跃查询;不得恢复为一把锁串行所有页面请求。 - 必须设置连接超时、查询超时、慢查询冷却和连接失败熔断;一次失败后进入冷却,已有旧快照时继续提供本地数据,不得连续重试。 - 上游 API 必须保留 `X-Caiwu-Data-Status` 和 `X-Caiwu-Data-Synced-At` 响应头;验收同时检查数据状态和同步时间,不能只看 HTTP 200。 - `JIANSUN_ENABLED` 默认关闭;只允许在现有只读访问方式完成受控连通性和单查询探测后,通过服务器私有 `runtime/.env` 开启。 - 首次启用必须同时设置 `JIANSUN_ALLOWED_SCOPES`,先开放已完成探测的小表范围;不得用 `*` 跳过核心大表的独立验证。 - 当前方案是近实时查询快照,不得冒充完整行级增量复制。没有可靠变更标记时,禁止定时全表扫描;历史一致性只能采用低频、小批量、可中止的核对。 - 首次全量历史数据同步必须单独评估行数、时间窗口和上游低峰期,不得在日常发布时自动执行。 - 上游地址、账号、密码只允许存在于服务器私有环境配置;代码、提交、PR、共享文档和日志中一律不得出现真实值。 详细 SOP 见 `docs/开发与部署SOP.md`。