yeg
2 天以前 f2cca8fe463efe96ad8d949a40bbee52baf89d8c
AGENTS.md
@@ -12,28 +12,76 @@
采用单上下文布局:根目录 `CONTEXT.md`,ADR 位于 `docs/adr/`。详见 `docs/agents/domain.md`。
### 工作范围:只动支付
### 工作范围:按业务域分工,不要越界
本仓库由多人分工,且约定**互不越界**:另一位同事负责支付以外的全部业务,本会话(AI 协作)只负责
**支付链路**——汇付/斗拱进件、支付、核销后的资金确认、自动结算与结算记录、退款,以及验证这条链路
所必需的本地库与工具改动。
本仓库由多人**按业务域分工**(支付链路一人,其余业务一人),彼此约定**互不越界**——越界改动会在
git 合并时产生大量冲突。本节适用于**所有**在仓库里工作的人和 AI 会话,与具体是谁无关。
其他业务(家属卡、洗车、停车、票券包、权益规则、资讯、各类申请审核等)**只做只读排查**:可以读代码、
查库、跑 SQL、给出结论和建议;**不要修改这些业务的代码、迁移和前端**。改多了会在 git 合并时产生大量
冲突,这是约定要避免的代价。
需要修其他业务的缺陷时,把「现象 + 根因 + 证据 + 建议改法」整理成 Markdown 交给用户转给同事,不要直接动手。
共享文件更要克制(`talent-card-admin/src/api/admin.ts`、`src/router/index.ts`、`src/layouts/AdminLayout.vue`、
`talent-card-server/src/main/resources/application.yml`、`AdminBusinessService.java`、`CONTEXT.md`):
只做支付相关的**增量小改**,不要顺手重构或格式化别人的区域。
- **只改用户本次指派范围内的代码、迁移和前端。** 范围以用户的说明为准;用户没说清、或任务看起来横跨
  多个业务域时,先问,不要自己扩大范围。
- **范围外的业务只做只读排查**:可以读代码、查库、跑 SQL、给出结论和建议,但不要直接改它的代码、
  迁移和前端。域划分大致是:**支付链路**=汇付/斗拱进件与开通、支付、核销后的资金确认、自动结算与
  结算记录、退款;**其余业务**=家属卡、洗车、停车、票券包、权益规则、资讯、各类申请审核等。
  (根目录 `CONTEXT.md` 是**术语表**,里面没有代码位置。)
- 需要修范围外的缺陷时,把「现象 + 根因 + 证据 + 建议改法」整理成 Markdown(放
  `.scratch/<feature-slug>/issues/`)交给用户转给该业务的负责人,不要直接动手。
- **迁移编号是全仓共享的**:新增迁移前先看 `talent-card-server/src/main/resources/db/migration/` 里当前
  的最大版本号,避免与他人撞号。
- **共享文件更要克制**(`talent-card-admin/src/api/admin.ts`、`src/router/index.ts`、
  `src/layouts/AdminLayout.vue`、`talent-card-server/src/main/resources/application.yml`、
  `AdminBusinessService.java`、`CONTEXT.md`):只做自己范围内的**增量小改**,不要顺手重构或格式化
  别人的区域。
### 服务器测试与数据库
后端测试跑在共享的 MySQL 测试库上。跑测试用 `talent-card-server/scripts/run-server-tests.ps1`,
重置库用 `talent-card-server/scripts/reset-test-db.ps1`,并遵守:已执行的迁移只追加不修改、同一
checkout 一次只跑一个 Maven 构建、不要 `drop database`。详见 `docs/agents/testing.md`(含 3 项已知
基线失败,不要为证明它们"是既有的"而重复造 worktree)。
checkout 一次只跑一个 Maven 构建、不要 `drop database`。详见 `docs/agents/testing.md`(**开发库与
测试库是哪两个库、什么版本**、3 项已知基线失败,以及一类会随测试库累积而出现的环境相关失败;不要为
证明它们是"既有的"而重复造 worktree)。
### 攀枝花政务云服务器:操作纪律(务必遵守)
这台机器**没有公网自服务控制台**——console/VNC 只在「云管理方」手里,进去只有一条路:堡垒机
(`172.18.105.9`)。**一旦把这条路弄断,你和用户谁都进不去,只能求服务商。** 2026-09-21 已经发生过
一次(docker 网桥占用 `172.18.0.0/16`,与堡垒机网段冲突,回程路由被劫走)。以下每条都是那次事故立的:
- **只在用户明确授权后动手。** 用户说"先别干活"、或语义模糊(例如只说"我们继续吧")时,**只给方案和
  命令,不执行**。事故当天就是凭一句模糊的"继续吧"动了手。
- **改网络/路由/防火墙/端口/SSH 之前,先确认带外通道可用。** 没有 console/VNC 兜底,这类改动一律不做。
- **改之前先枚举已知网段**,不要只看"自己那一段":
  | 网段 | 是谁 |
  |---|---|
  | `172.192.19.0/24` | 服务器自己,网关 `172.192.19.254` |
  | **`172.18.0.0/16`** | **堡垒机所在网段**(堡垒机连服务器的来源是 `172.18.140.254`) |
  | `192.169.1.10` | 办公侧(VPN 客户端来源) |
  | `192.168.110.0/24` | 办公室开发库 `192.168.110.13` |
- **不要在这台机器上引入 docker(2026-09-21 已卸载,别再装回去)。** 两个原因:一是它的网桥默认
  地址池会依次分到 `172.17`、`172.18`、`172.19`…,正好撞上堡垒机网段 `172.18.0.0/16`,回程路由被劫走
  就直接失联;二是这台机器的虚拟 CPU 缺 SSE4.2/POPCNT,以 x86-64-v2 为基线的镜像根本跑不起来(见下)。
  **MySQL/Redis 一律原生装。** 万一将来确实要重新引入,**必须在建任何网络之前先钉死地址池**:
  `"default-address-pools": [ { "base": "10.201.0.0/16", "size": 24 } ]`(同时把 `data-root` 指向
  `/data`——40G 系统盘装不下镜像)。
- **一次只改一件事,每步之后先复检堡垒机通道还在**,再走下一步。
- **高危改动挂自动回滚**:`systemd-run --on-active=5min /bin/bash -c '<撤销命令>'`,确认通道正常后再
  取消它。最坏情况 5 分钟后自己恢复,不必求人。
- **给服务商的命令要一次说准、可直接复制、并写出期望输出。** 消息要经**两跳**(对接人 → 云管理方),
  每次返工就是几十分钟。事故当天给的 `docker compose down` 缺了 `-f`(本仓的 compose 叫
  `docker-compose.prod.yml`,不是 compose 的默认文件名),白费一跳。
- **不要把凭据写进聊天。** 必须提供给执行人时,事后立刻轮换。
**这台机器的硬约束(改环境前先看):**
- **虚拟 CPU 缺 SSE4.2/POPCNT/AVX**(KVM 上是老的 QEMU 型号,物理 CPU 其实够用)→ **任何以
  x86-64-v2 为基线的镜像都跑不起来**:官方 `mysql:8.4` 会 `Fatal glibc error: CPU does not support
  x86-64-v2` 循环退出(exit 127)。Redis 官方镜像正常,Ubuntu 自己的包都正常。要跑这类镜像,得请服务商
  把虚拟机的 CPU 型号改成 `host-passthrough`。
- **出网**已开通,是**任意公网地址**(不是域名白名单)。但 **Docker Hub 直连不通**(`registry-1.docker.io`
  连接被重置),拉镜像走 `public.ecr.aws/docker/library/<name>`。
- **入向**只有 `8081`/`8082` 开放(公网地址 `117.172.73.106`);`80`/`443`/`8080` 要备案号才能开。
- **办公网到 `172.192.19.0/24` 没有路由**,所以只能走堡垒机,不能直连。
### Git 提交