diff --git a/AGENTS.md b/AGENTS.md index bbd3da12..560474f7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,6 +32,8 @@ ## 3. 新人使用 AI 的固定流程 +新人本地接入的唯一手工动作是启动 Docker Desktop、在网页中登录,以及输入一次负责人提供的系统数据库密码。拉取代码、构建、初始化、本机引导库迁移、缓存清理、服务启动、页面打开、系统数据库切换后的两套上游验证和数据字典同步均由 Codex 完成;不得把命令、迁移、连接参数、TLS、证书、`APP_KEY` 或上游配置交给新人处理。 + 1. 先确认任务目标、验收方式、影响范围和不能触碰的模块。 2. 进入正确项目和分支,先执行 `git status`;看到陌生改动,先停止并说明情况。 3. 向 AI 提供:任务目标、当前分支、报错或现象、相关文件、不可修改的范围。 @@ -166,6 +168,6 @@ - 本机临时引导库的新增迁移由 `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` 来掩盖共享配置读取错误。 - 系统数据库统一保存应用数据、云数据库配置、上游数据字典和生产共享快照,但不是 SQL Server 网络代理。本地开发应用直接使用系统数据库中的连接资料访问两套上游;前提是该开发机网络本身能够到达数据库端点。 -- 开发验收必须在不复用负责人现有 `.env`、登录会话、容器或数据库卷的全新隔离环境中完成:只填写一次系统数据库密码,然后分别验证两套来源的共享配置解析、`SELECT 1` 和至少一个真实业务表/视图的只读查询。只在负责人已配置环境中测试不算新人接入验收。生产验收还需验证共享快照。所有输出不得包含地址、账号、密码、完整 DSN 或敏感业务行。页面和正式 Repository 仍必须通过 `UpstreamReadOnlyQuery` 执行固定、参数化的 `SELECT`,禁止写操作和任意 SQL 输入。 +- 开发验收必须在不复用负责人现有 `.env`、登录会话、容器或数据库卷的全新隔离环境中完成:只填写一次系统数据库密码,然后分别验证两套来源的共享配置解析、`SELECT 1` 和至少一个真实业务表/视图的只读查询。只在负责人已配置环境中测试不算新人接入验收。生产验收还需验证共享快照。验收报告必须逐个来源明确写出来源标识、目标数据库和 Schema、验证的表或视图、读取字段、返回行数、耗时、`direct/fresh/stale` 状态及失败阶段,禁止只给“能连接”或“不能连接”的含糊结论。连接资料由程序自动读取和使用,不让新人手工配置;页面和正式 Repository 仍必须通过 `UpstreamReadOnlyQuery` 执行固定、参数化的 `SELECT`,禁止写操作和任意 SQL 输入。 详细 SOP 见 `docs/开发与部署SOP.md`。 diff --git a/LOCAL_DEPLOY.md b/LOCAL_DEPLOY.md index 0c4ccada..16cf2e69 100644 --- a/LOCAL_DEPLOY.md +++ b/LOCAL_DEPLOY.md @@ -6,6 +6,8 @@ http://127.0.0.1:18088 ``` +新人只需要启动 Docker Desktop、在网页中登录,并输入一次系统数据库密码。拉取代码、执行初始化、迁移本机引导库、启动服务、清理缓存、验证系统数据库、同步数据字典和验证两套上游均由 Codex 完成。 + ## 先理解数据库关系 本地 Compose 中的 MySQL 只负责第一次启动,让开发者能够使用临时账号进入系统。 @@ -25,15 +27,15 @@ http://127.0.0.1:18088 - 每台开发机可以使用自己的 `APP_KEY`,禁止复制生产环境或其他开发者的 `APP_KEY`; - 不需要在本机填写 `DB_JIANSUN_*` 或 `DB_OPERATIONS_REPLICA_*`。 -系统数据库保存云数据库配置、活跃查询登记和共享查询快照,但不会自己执行 SQL,也不是 SQL Server 网络代理。日常开发由具备上游连通性的生产后台刷新进程读取云数据库并写回共享快照,普通开发机不需要配置白名单、VPN、SSH 隧道或本机上游凭据。 +系统数据库保存云数据库配置、活跃查询登记、数据字典和生产共享查询快照,但不会自己执行 SQL,也不是 SQL Server 网络代理。本地开发环境从系统数据库自动读取两套上游连接资料,然后由本地应用直接执行代码中的固定只读查询;生产环境继续由后台刷新进程生成共享快照。 -已有快照会直接返回。完全没有快照时,本机页面会先登记这次查询;如果本机网络不能访问上游,本次请求可能暂时显示不可用,但生产后台进程会在代码已经合并部署且数据范围已获准后读取该登记并生成共享快照。不得为了消除这次提示而复制其他人的 `.env`、`APP_KEY` 或数据库密码。 +新人不填写上游地址、账号、密码、TLS、证书、白名单、VPN 或 SSH 隧道配置。连接资料统一由系统自动解析;若本机网络确实不能到达某个上游,Codex 必须直接报告失败发生在 DNS、TCP、TLS、登录、数据库、Schema 还是业务查询阶段,不能把网络问题说成代码范围或共享快照问题。 ## 第一次启动 前提:Docker Desktop 已启动。 -在 Git Bash、WSL、macOS 或 Linux 终端中执行: +下面的命令由 Codex 在 Git Bash、WSL、macOS 或 Linux 终端中执行,不交给新人: ```bash bash deploy/local-init.sh --build @@ -48,11 +50,11 @@ bash deploy/local-init.sh --build 5. 检查安装状态、数据库连接、运行目录和登录页; 6. 提示下一步配置系统数据库。 -首次临时登录凭据保存在 `runtime/bootstrap-credentials.env`。脚本只显示文件路径,不打印密码。不要提交、截图或转发该文件。 +首次临时登录凭据保存在 `runtime/bootstrap-credentials.env`,仅用于登录本机引导库。 这个账号只存在于本机临时数据库中。系统数据库切换完成后,请使用系统数据库里属于自己的账号登录,不要继续把临时账号当作团队共享账号。 -初始化中断后直接重新执行 `bash deploy/local-init.sh` 会复用已有镜像并从数据库初始化阶段继续。只有依赖、Dockerfile 或构建资源发生变化时才使用 `--build`;确认只启动现有镜像时可使用 `--skip-build`。 +初始化中断后,Codex 直接重新执行 `bash deploy/local-init.sh`,脚本会复用已有镜像并从数据库初始化阶段继续。只有依赖、Dockerfile 或构建资源发生变化时才使用 `--build`;确认只启动现有镜像时可使用 `--skip-build`。 拉取新代码后再次运行该脚本时,本机临时引导库会自动更新;连接团队共享系统数据库后,这项自动更新会安全跳过。普通开发者任何时候都不需要执行 `php artisan migrate`,也不得对团队共享系统数据库自行迁移。 @@ -82,34 +84,35 @@ SYSTEM_DATABASE_MODE=shared ## 验收共享云数据库 -仅看到两条云数据库记录并不代表业务读取已经成功。验收时应在应用容器内完成: +仅看到两条云数据库记录并不代表业务读取已经成功。系统数据库连接后,Codex 必须在应用容器内自动完成: -1. 确认两条记录都显示启用; -2. 确认共享密码可以解锁; -3. 至少调用一个已经登记并产生共享快照的真实业务查询; -4. 检查页面或 API 的数据状态和同步时间; -5. 在不提供本机上游凭据、且不依赖本机直连的情况下确认结果可以重复读取。 +1. 确认当前是 `shared` 系统数据库模式,本机上游覆盖关闭; +2. 确认两条共享连接资料均能由 `UpstreamSourceRegistry` 正确解析; +3. 分别完成数据库连接和 `SELECT 1`; +4. 分别对至少一个真实业务表或视图执行限定字段、限定行数的只读查询; +5. 同步或读取两套来源的数据字典; +6. 逐个来源报告来源标识、数据库和 Schema、验证对象、读取字段、返回行数、耗时、`direct` 状态和失败阶段。 -两个上游的 `SELECT 1`、首次真实查询和慢查询观察属于发布验收,由具备网络连通性的生产刷新节点或获授权的诊断环境执行,不要求每位开发者在自己的电脑上重复连接。 - -禁止为了排错复制别人的 `.env`、生产 `APP_KEY` 或云数据库密码。 +不能用端口连通、共享密码可解密、数据字典存在或 `SELECT 1` 成功代替真实业务行验收;也不能因为缺少 Repository、`scope` 或生产快照,就判断本地开发无法读取上游。 ## 需要尚未缓存的新表或字段 -系统不会自动复制两个上游数据库的全部表。开发者需要系统数据库中尚无快照的数据时,按下面流程处理: +系统不会自动复制两个上游数据库的全部表。开发者需要新表或字段时,由 Codex 按下面流程完成: -1. 先确认业务目的、来源标识、所需表和字段、筛选条件、排序方式、最大返回量、公司/权限范围及建议缓存时间; -2. 在自己的任务分支中通过 `UpstreamReadOnlyQuery` 实现固定、参数化的只读查询,页面只能调用 Repository,不能直接拿 PDO; -3. 为查询定义稳定的 `scope`,通过 `UpstreamQueryCache` 读取,并在对应 `UpstreamSnapshotRefresher` 中登记同一范围; -4. 分支开发阶段使用脱敏 fixture 或测试替身完成页面和错误状态验证;尚未合并的查询不会被生产后台进程执行; -5. 通过测试和代码检查后合并到 `main`,先部署代码,再由负责人只开放这一个精确范围,禁止使用全局 `*`; -6. 首次页面请求会把查询登记到共享系统数据库,生产后台进程随后读取上游并写入首份共享快照; -7. 再次访问应返回 `fresh` 或 `stale`,并验证另一台开发机可以读取同一快照且不会再次访问上游。 +1. 从共享数据字典确认来源、表或视图和字段;目录缺失或过期时由 Codex 执行 `upstream:schema:sync`; +2. 在本地通过 `UpstreamReadOnlyQueryFactory` 执行一次限定字段、限定行数的真实只读探索查询,不需要先有 Repository、`scope` 或生产快照; +3. 确认业务目的、字段含义、筛选条件、排序方式、最大返回量、公司/权限范围及建议缓存时间; +4. 在任务分支中通过 `UpstreamReadOnlyQuery` 实现固定、参数化的只读查询,页面只调用 Repository; +5. 为生产查询定义稳定 `scope`,通过 `UpstreamQueryCache` 读取,并在对应 `UpstreamSnapshotRefresher` 中登记同一范围; +6. 完成自动测试和本地真实只读验收后合并到 `main`; +7. 生产部署后生成首份共享快照,再验证第二个应用实例复用该快照。 系统数据库中只保存受控查询的标识、参数、访问范围和结果,不保存可执行的任意 SQL。需要调整查询时必须修改代码并重新走合并、部署和验收流程。 ## 常用命令 +本节只供 Codex 排错和验收使用,新人不需要手工执行。 + 所有 Laravel 命令都必须使用 `-u www-data`。省略后 Docker 会默认使用 `root`,可能生成网页进程无法写入的缓存、日志或系统数据库备份,造成“测试通过但页面 500”。 ```bash diff --git a/README.md b/README.md index 377dbc3b..172dfd62 100644 --- a/README.md +++ b/README.md @@ -4,30 +4,28 @@ ## 开发者快速开始 -1. 启动 Docker Desktop。 -2. 在仓库根目录执行: +新人只需要做两件事: -```bash -bash deploy/local-init.sh --build -``` +1. 启动 Docker Desktop; +2. 在系统数据库页面输入负责人提供的系统数据库密码。 -3. 打开 `http://127.0.0.1:18088`。 -4. 首次从脚本提示的本机私有凭据文件读取临时账号并登录;不要把内容发到聊天或提交到 Git。 -5. 打开“系统设置 → 数据库管理 → 系统数据库”。 -6. 点击系统数据库的“连接”,只填写负责人提供的系统数据库密码。 -7. 使用系统数据库中属于自己的账号重新登录。 +其余工作交给 Codex:拉取最新 `main`、执行 `bash deploy/local-init.sh --build`、处理本机引导库迁移、启动服务、清理缓存、打开 `http://127.0.0.1:18088`,并在连接后自动核对两套上游、数据字典和真实只读查询。Codex 不得把这些命令、迁移或排错步骤转交给新人执行。 + +首次登录账号由初始化脚本生成并保存在本机私有凭据文件中。连接系统数据库成功后,临时登录会自动失效,改用系统数据库中属于自己的正式账号登录。 连接成功后,用户、侧边栏、系统设置、云数据库登记和共享快照会自动统一。不需要填写主机、端口、库名、账号、TLS、证书或两个云数据库密码,也不要复制生产环境或其他开发者的 `APP_KEY`、`.env`。 +Codex 的接入验收不能只回答“成功”或“失败”,必须逐个来源报告:来源标识、数据库和 Schema、验证对象、读取字段、返回行数、耗时、数据状态及失败阶段。连接资料由系统自动处理,不属于新人操作项。 + 完整步骤和排错说明见 [LOCAL_DEPLOY.md](LOCAL_DEPLOY.md)。 ## 数据库边界 - 本机 MySQL 只负责第一次启动和临时登录,不是团队业务数据源。 - 系统数据库统一保存应用用户、系统设置、侧边栏配置和云数据库连接记录。 -- 云数据库属于只读上游,业务必须经过固定适配器、允许范围和共享按需查询快照读取。 -- 系统数据库保存查询登记和共享快照,但不会执行 SQL,也不是 SQL Server 网络代理;标准模式由具备上游连通性的生产后台刷新进程获取数据。 -- 开发者需要尚未缓存的新表或字段时,先在分支中实现固定只读查询、数据范围和刷新器;合并部署后再开放该范围,由后台进程生成首份共享快照。 +- 云数据库属于只读上游。本地开发从系统数据库自动取得连接资料并执行固定只读查询;生产页面使用共享按需查询快照。 +- 系统数据库保存查询登记、数据字典和生产共享快照,但不会执行 SQL,也不是 SQL Server 网络代理。 +- 开发者需要新表或字段时,Codex 先通过共享数据字典和通用只读入口完成真实数据探索,再实现 Repository、生产范围和刷新器;新人不需要配置上游或执行探测命令。 - 不得把数据库密码、连接串、生产 `APP_KEY`、Token、SSH 私钥或 `runtime/.env` 提交到 Git。 ## 开发和发布 diff --git a/docs/开发与部署SOP.md b/docs/开发与部署SOP.md index 6779b891..f0fd4546 100644 --- a/docs/开发与部署SOP.md +++ b/docs/开发与部署SOP.md @@ -19,6 +19,8 @@ ## 2. 每台开发机只做一次的设置 +新人只负责启动 Docker Desktop、在网页中登录,以及输入一次系统数据库密码。下面涉及仓库、脚本、构建、迁移、缓存、容器、数据库验证和排错的动作均由 Codex 执行,不能把命令转交给新人。 + 1. 安装并启动 Docker Desktop,使用 WSL2 后端。 2. 在 Docker Desktop 的 `Settings -> Resources -> Advanced` 中: - Docker 虚拟磁盘上限建议 60GB; @@ -197,14 +199,16 @@ php artisan upstream:snapshots:refresh-all 生产环境 -> 登记 scope + 参数 -> 后台固定刷新器 -> 共享查询快照 ``` -开发者需要先确认表名和字段时,进入“系统设置 → 数据库管理 → 查看数据字典”。任何能直连上游的开发环境或生产刷新节点都可以低频读取两套上游的 `INFORMATION_SCHEMA`,把表、视图、字段、类型和可空信息保存到共享系统数据库 `upstream_schema_columns`。目录同步失败时保留最近一次完整结果,不会清空其他来源。可手动执行: +开发者需要先确认表名和字段时,进入“系统设置 → 数据库管理 → 查看数据字典”。任何能直连上游的开发环境或生产刷新节点都可以低频读取两套上游的 `INFORMATION_SCHEMA`,把表、视图、字段、类型和可空信息保存到共享系统数据库 `upstream_schema_columns`。目录同步失败时保留最近一次完整结果,不会清空其他来源。需要更新目录时由 Codex 自动执行: ```bash php artisan upstream:schema:sync php artisan upstream:schema:sync operations_replica ``` -数据字典只解决“有哪些表和字段”,不复制业务行,也不允许在系统数据库中保存任意 SQL。缺少现成 Repository、页面适配器、生产 `scope` 或共享快照时,本地开发并没有被挡住:开发者或 Codex 可以通过 `UpstreamReadOnlyQueryFactory::forSource()` 对目录中选定的对象执行少量、限定字段和返回量的只读 `SELECT/WITH`,先确认真实业务行和字段含义。该探索查询不需要修改云数据库配置或等待生产刷新,但不得输出敏感业务行,也不得接受用户输入的原始 SQL。 +数据字典只解决“有哪些表和字段”,不复制业务行,也不允许在系统数据库中保存任意 SQL。缺少现成 Repository、页面适配器、生产 `scope` 或共享快照时,本地开发并没有被挡住:Codex 通过 `UpstreamReadOnlyQueryFactory::forSource()` 对目录中选定的对象执行少量、限定字段和返回量的只读 `SELECT/WITH`,确认真实业务行和字段含义;新人不需要自己编写或执行探测 SQL。该探索查询不需要修改云数据库配置或等待生产刷新,也不得接受用户输入的原始 SQL。 + +每次新人接入验收必须逐个来源明确报告:来源标识、数据库和 Schema、验证的表或视图、读取字段、返回行数、耗时、`direct/fresh/stale` 状态以及失败阶段。不能只报告端口通、登录成功、`SELECT 1` 成功,也不能用“已有配置”“等待范围”代替真实业务只读查询。连接资料由系统自动读取并使用,不属于新人操作项。 确认数据后,再按下面的固定查询闭环把它实现成可合并、可测试、可部署的正式功能。Repository 是正式业务代码的交付要求,不是本地访问数据库和开始开发的前置条件。