Files
fire-safety-ymd/PROJECT_STATE.md
2026-09-05 16:50:56 +08:00

121 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# fire-safety-ymd 项目当前状态
| 项 | 内容 |
| --- | --- |
| 最近更新 | 2026-09-05 |
| 当前分支 | `main` |
| 当前阶段 | 对话、SuperAgent、空间 MCP 与测试环境容器部署基线已完成;目标机首次构建排障中 |
| 当前重点 | 解决目标服务器访问 Go module proxy 超时,完成容器启动后再验证公网链路 |
## 1. 当前 Checkpoint
- 名称:`fire-safety-ymd-test-server-build-network-recovery`
- 状态In Progress
- 目标:在不关闭 Go module 校验的前提下,让 Docker 构建可显式选择目标服务器可达且经认可的模块代理,完成 `/home/firee-safety-ymd` 首次镜像构建与容器启动。
- 非目标:替用户提交或推送 Git、直接修改远程服务器、创建数据库容器、迁移生产数据、签发证书、改变 DNS/安全组、实现真实用户认证、动态授权、会话持久化或生产审计。
当前进展:
- `Dockerfile` 使用显式 Go/Alpine 版本的多阶段构建,在构建阶段执行全部 Go 测试最终镜像只包含静态服务二进制、CA 和时区数据,并以非 root 用户运行。
- Docker build 支持通过 `FIRE_SAFETY_BUILD_GOPROXY` 选择目标机可达的可信 Go module proxy默认仍为官方代理并保留 checksum database`git` 只存在于 builder构建代理配置在运行容器中强制清空。
- `compose.yaml` 只运行一个 API 实例,从未提交的 `.env` 注入配置,强制清空一次性迁移 DSN把容器内 8080 发布到宿主机 `127.0.0.1:16587`,并设置健康检查、只读文件系统、权限收紧和日志轮转。
- 现有 PostgreSQL/PostGIS 不进入 Compose同宿主机数据库需要使用容器可达的宿主机地址且仍需受 `listen_addresses``pg_hba.conf` 和防火墙约束。
- Nginx 示例增加 HTTP 到 HTTPS 跳转和 HTTP 429 JSON 限流响应,仍不比较、保存或注入 Chat、MCP、SuperAgent 或数据库 Secret。
- 运维手册记录 Git 前置条件、服务器目录、Secret 权限、Compose/Nginx 启停、Chat/MCP 冒烟、SuperAgent 回调、更新和回滚。
已实现验收项:
- 镜像构建上下文排除 `.env`、密钥、证书、SQL、Excel、文档和本机构建产物运行时镜像不包含 Go 工具链或源码。
- Compose 配置不包含明文 Secret且没有数据库容器、数据卷或迁移命令现有业务数据库不会被部署动作重建。
- Nginx 上游固定为宿主机回环地址,兼容 Chat SSE 禁用缓冲和自动重试,未列出路径固定 404。
- 目标机执行步骤包含不渲染 `.env` 内容的 Compose 检查、`nginx -t` 前置门禁和可恢复的配置替换。
- 目标服务器已开始部署Nginx 配置语法检查通过,但 Docker 构建在 `go mod download` 阶段因访问 `proxy.golang.org:443` 超时而停止,应用尚未监听 16587。
## 2. 当前优先级
1. 为 Docker build 配置目标服务器实际可达、经运维认可的 Go module proxy保留 `go.sum`/checksum database 校验并重新构建。
2. 由用户审查本 checkpoint 变更后提交并推送 `origin/main`;服务器只部署明确提交的 revision。
3.`/home/firee-safety-ymd` 构建并启动 Compose确认宿主机 16587 只绑定回环地址、容器内 8080 健康可达且数据库连接正常。
4. reload 已通过语法检查的 Nginx 配置,只公开 HTTPS 兼容路径、`/mcp` 和可选 `/health`
5. 使用项目专属测试 Key 和已发布消防 Profile 做兼容 `completion` 首轮/多轮真实冒烟,核对最终回答、用量和会话复用。
6. 为所有查询表补齐适用 GiST 索引并验证查询计划;当前小数据可做联调,但生产前必须完成索引与并发验证。
7. 设计真实用户身份、动态角色/区域授权、共享会话、限流、Secret 轮换、指标和持久审计。
## 3. 已确认事实
- 仓库已初始化 Git当前分支是 `main`,已有远程 `origin`;基线提交 `8a6c31c` 已推送到 `origin/main`
- `docs/import/字段组.xlsx``docs/import/数据表映射.xlsx` 是用户已有、已暂存的变更,本 checkpoint 未修改。
- 用户已使用项目只读 probe 成功连接数据库 `fire_safety_ymd`PostGIS 报告版本 `3.3 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`8 表合计 4,055 条记录。
- 实库 4,048 条非空几何已在 2026-09-05 的受控事务中从 SRID 0 补齐为 SRID 4326坐标 extent 约为经度 121.16 至 121.93、纬度 37.07 至 37.49,类型与预期一致且未发现 WGS84 数值越界。数据提供方确认 8 表源数据均为 EPSG:4326 且无坐标偏移,严格 readiness 已通过。
- 实库包含 7 条空几何;防火网格 4 条、林区工矿企业 4 条、墓地坟区 27 条无效面几何。用户决定首版不修复原始几何,由 MCP 排除并明确告警。
- 实库仅防火网格表报告存在 GiST 几何索引,其余 7 张表尚未发现 GiST 几何索引。
- 防火通道首次重导在约第 256 条因 `Geometry has Z dimension but column does not` 中止,证明源数据混合二维与 Z 维度;用户将 `st_2_xianyoufanghuotongdao.geom` 改为不限定 typmod 的 `geometry` 后报告重导成功。原始列不得无审查改回二维 `geometry(GEOMETRY)`,也不得静默 `ST_Force2D` 丢弃 Z。
- 每张表的 2 条本地样例足以确定首版字段映射;样例不能证明全库质量或实时状态。
- 原始导出样例的 `geom` 列均声明为 `geometry(GEOMETRY)`,但该声明不兼容防火通道中的 Z 记录;防火通道实库导入列已按用户现场操作改为裸 `geometry`。数据提供方允许当前二维算法忽略 Z但原始 Z 仍须保留,不能对原始表执行 `ST_Force2D`
- Go module 当前使用临时名称 `fire-safety-ymd`,本地工具链为 Go `1.26.6`
- 直接第三方依赖为 `github.com/jackc/pgx/v5 v5.10.0`HTTP、JSON-RPC/MCP 和测试仍使用 Go 标准库。
- 服务默认监听 `:8080``GET /health` 仍只是 liveness不访问外部依赖。
- 用户对话 API、SuperAgent Open API Adapter 和 MCP endpoint 都默认关闭Chat Bearer、Open API Key 和 MCP Token 属于三个独立信任方向并禁止复用。
- `/api/chat` 已实现单进程内存会话映射、同会话并发 Run 冲突和严格 SSE 最终回答;模拟 Provider 端到端测试通过,真实 SuperAgent 尚未通过该入口联调。
- 可选兼容入口已实现截图所示路径、`xtoken``input.prompt/session_id``event: result` 外形;正文仍只在严格成功的 `stop` 事件中出现,不是 DashScope 全量 API。
- `Dockerfile``.dockerignore``compose.yaml` 已建立测试部署基线;容器单实例运行,容器内 8080 仅发布到宿主机 `127.0.0.1:16587`,一次性迁移 DSN 在服务容器中强制为空。
- `deploy/nginx/fire-safety-ymd.conf.example` 已将公网调用指向宿主机 `127.0.0.1:16587`,再由 Docker 映射到容器 8080配置不保存或注入任何 Provider/Chat/MCP Secret。目标机仅 `nginx -t` 语法检查已通过reload 和 HTTPS 实际响应尚未验证。
- 用户确认真实数据包含大量镇街环境变量不适合枚举全量值MCP 现支持显式数据库全范围 `all` 和默认镇街白名单 `town_allowlist` 两种服务端范围。
- 用户选择先实现简单地名能力、后续再优化;当前只查询既有森林防火记录,不调用外部地图服务,也不把候选代表点自动认定为演练点。
- 本地真实 MCP 冒烟已完成7 个工具均成功访问实库响应和错误边界符合契约该结果不等于公网、SuperAgent 或生产并发已验证。
- 防火通道现有字段不能支持可靠路线规划;防火网格现有字段不能支持实时队伍位置或正式集结点。
## 4. Known Issues 与未确认项
- 目标 PostgreSQL 的只读连接和 PostGIS 3.3 已由 probe 验证数据库版本、TLS/网络生产拓扑、凭证轮换和审计仍未确认。
- 35 条无效面几何和 7 条空几何会被查询排除;尤其 4 条无效防火网格可能造成所属网格和责任中队结果缺口27 条无效墓地面可能造成风险区域漏项。
- 除防火网格外 7 张表缺少 GiST 几何索引;当前 geography 距离表达式的生产索引方案需根据实库查询计划确认。
- 水源/设施 `syzt`、水源 `hc_datetime` 等字段的枚举、单位、时区和更新责任人尚未确认。
- SuperAgent MCP 的公网/内网 URL、TLS、网络白名单、Header 行为、Token 注入和轮换尚未联调。
- `/api/chat` 静态 Bearer 和兼容路径 `xtoken` 只适用于受控联调,浏览器用户可以看到它;真实用户身份、动态授权、生产速率限制和滥用防护尚未实现。
- 目标公网机器的 Docker/Compose 和 Nginx 版本、配置 include 层级、证书、DNS、安全组及 PostgreSQL 网络拓扑尚未完整验证;用户已开始远程部署,仓库资产与服务器现场配置仍需完成一致性核验。
- 目标服务器可以拉取 Docker 基础镜像元数据,但连续两次访问 `proxy.golang.org:443` 均在约 91 秒后超时当前不能据此判断替代代理、GitHub direct 或所有外部 HTTPS 都不可达。
- Chat 会话只在单个 Go 进程内存中保存;重启或多实例切换会丢失上下文,且当前没有历史查询、持久审计或主动取消 Provider Run。
- 当前 `all`/`town_allowlist` 都是服务账号静态范围,不是最终用户级授权;`all` 会授权当前数据库中 MCP 固定查询表内所有镇街和镇街字段为空的记录,身份提供方、角色、租户和精确位置权限尚未确定。
- 地名搜索是无索引的有界包含匹配;真实数据量下的耗时、重名率和名称字段质量尚未验证,生产优化可能需要标准地名表、别名词典或 `pg_trgm` 索引。
- 镇街或村庄名称可能匹配多条资源/网格;线面只返回只读计算的代表点,不能直接作为真实演练点。
- 只实现最小结构化运行日志,没有持久审计、指标、限流网关或数据源版本。
- 路线规划缺少路网拓扑、坡度、路面、宽度、车辆限制、封路、实时火场和天气数据。
- 队伍集结缺少正式集结点、实时定位、战备状态、人员/车辆/装备和容量数据。
- `fire-safety-ymd` 正式 module path 与 CI/部署 Go 版本仍待确认。
## 5. Next Checkpoint
建议:`fire-safety-ymd-container-public-entry-live-smoke-test`
完成条件:
- 用户提交并推送本 checkpoint 后,目标机能在 `/home/firee-safety-ymd` clone 或 `git pull --ff-only` 到明确 revision。
- `docker compose build --pull``up -d` 和容器健康检查通过,宿主机 16587 只绑定 `127.0.0.1`,运行容器中没有迁移凭证。
- 在目标机替换安全 App ID、执行 `nginx -t` 后 reload并验证 TLS、HTTP 到 HTTPS 跳转、429 和未列出路径 404。
- 使用无敏感信息的问题验证兼容首轮 `null -> stop`、后续 `session_id` 复用、错误 xtoken、断流和超时。
- 配置 SuperAgent 对公网 `/mcp` 的独立 Bearer验证真实工具调用、TLS 和 warning 保留。
- 不在输出、命令历史、Nginx、镜像层或 Git 中记录任何 Secret。
## 6. 验证记录
- `gofmt -w ./cmd ./internal`:通过。
- `GOCACHE=/private/tmp/fire-safety-go-cache go test -count=1 ./...`:通过;新增覆盖兼容 App ID、`xtoken`、CORS、严格请求子集、`null -> stop` SSE、会话复用映射、用量/模型名、错误脱敏和路由/应用装配;原有 Chat、SuperAgent、MCP/PostGIS 覆盖继续通过。
- `GOCACHE=/private/tmp/fire-safety-go-cache go vet ./...`:通过。
- `GOCACHE=/private/tmp/fire-safety-go-cache go test -race -count=1 ./...`:通过。
- 模拟 SuperAgent Chat 端到端:原生与兼容入口均通过;应用创建 Provider Session、发送消息、解析严格完成事件原生返回 `conversation/message/done`,兼容入口返回 `result` 且最终 `finish_reason=stop`
- Nginx配置已完成静态检查且未包含真实 Secret开发机未安装 Nginx。据用户截图目标机 `nginx -t` 已通过reload 和 HTTPS 实际响应尚未验证。
- Docker/Compose部署文件已通过 YAML/静态安全断言;开发机未安装 Docker。目标机已发起真实构建但未生成镜像`docker compose config --quiet`、健康状态和运行容器仍待现场确认。
- 构建代理回归检查:修复前静态反馈命令返回 `RED: Docker build has no configurable GOPROXY`;修复后确认 Compose build arg、Dockerfile `GOPROXY` 和运行容器清空边界,返回 GREEN。
- `CGO_ENABLED=0 GOOS=linux go build -buildvcs=false -trimpath ./cmd/server`:通过,生成 Linux 静态服务二进制;不替代目标机真实 Docker build。
- 目标机首次 Docker 构建:失败;`go mod download` 获取 `github.com/jackc/pgpassfile@v1.0.0` 时连接 `proxy.golang.org:443` 超时,镜像/容器未生成,随后 `curl http://127.0.0.1:16587/health` 得到 connection refused符合前置构建失败。
- 目标机 Nginx用户截图显示 `nginx -t` 配置语法检查成功;是否已 reload 以及 HTTPS 实际响应仍待确认。
- SRID 迁移预检:通过;使用临时 `admin` 连接确认 4,048 条候选、8 表 UPDATE 权限和 7 表 ALTER 权限,未输出 DSN 或业务记录。
- SRID 数据迁移:通过;事务更新 4,048 条非空几何7 张二维表改为 `geometry(Geometry,4326)`,防火通道保持裸 `geometry`,迁移前后几何载荷指纹与维度一致。
- 真实 PostGIS 严格 audit通过运行时只读账号报告 8 表 SRID 均为 4326、类型与范围门禁通过。预期保留 7 条空几何、35 条无效面几何和 7 张缺 GiST 索引表 warning。
- 本地真实 MCP 冒烟通过health、鉴权、Origin、方法限制、协议初始化、7 工具发现、7 tools/call、无结果、非法参数、响应一致性、字段脱敏、warning 和结构化日志均符合契约。第二轮实库查询约 0.35 至 0.99 秒。
- 数据导入:用户报告 8 份 SQL 已导入,防火通道在使用裸 `geometry` 保留混合二维/Z 后重导成功;这是现场反馈,不替代项目只读 probe 的最终验证。
- 真实 SuperAgent 对话与 MCP 联调:对话 API 仅完成模拟 Provider 端到端测试,真实消防 Profile 尚未测试MCP readiness 和本地真实工具冒烟已通过,公网 HTTPS 回调未配置。
- 样例 SQL未执行含受限数据的 `*.sql` 已被 Git 忽略。
- Git基线提交已存在并推送本 checkpoint 变更尚未提交,未执行自动 commit/push。