# apps/pbls/wwwroot/api/public/health/index.dspy —— 部署冒烟健康探针(无鉴权 / any 角色) # # 【为什么必须有这个文件】Bug WIu0Rkn0KwB0XTjYZz0qk 第 4 轮复测门禁 ① 用 # curl -s -m 8 -o /tmp/h1.txt -w 'HTTP=%{http_code}' http://127.0.0.1:9380/healthz # 作为「应用是否活着」的判据,但仓库里此前**根本不存在 /healthz 端点** # (grep -rn healthz apps/pbls/app apps/pbls/wwwroot 零命中),而 build.sh 步骤 14 # 自检用的却是另一条路径 /api/public/health(同样不存在)。两条探针路径都缺 → # 即便进程起来、端口监听,门禁 ① 也必然 HTTP=000/404,冒烟永远不可能转绿。 # 本文件补齐 build.sh 步骤 14 自检口径 GET /api/public/health;同批由 # wwwroot/healthz/index.dspy 提供复测门禁 ① 口径 GET /healthz(两者同逻辑,双路径都在 # scripts/load_path.py 以 'any' 角色逐条注册,无通配符)。 # # 【URL 映射】ahserver 按 website.root=wwwroot + processors['.dspy']='dspy' 解析: # wwwroot/api/public/health/index.dspy -> GET /api/public/health # 另在 wwwroot/healthz/index.dspy 放同逻辑副本 -> GET /healthz(复测门禁 ① 判活口径), # wwwroot/healthz.dspy -> GET /healthz.dspy(兼容带扩展名探测)。 # # 【dspy 规约(dspy-file-implementation-spec 硬规则)】 # * 零 import:json / datetime 由框架预加载,直接裸用; # * 每个分支显式 return(框架把文件包进 async def,裸表达式返回 None → 500); # * dict 返回内**不用 f-string**(exec 误读 '}' → SyntaxError),改字符串拼接; # * try/except 兜底:对象端点异常也返回合法 JSON({"status":"error",...}),不抛 500; # * json.dumps(..., default=str) 防 Decimal/datetime 序列化炸; # * 不返回任何敏感字段(库口令/密钥一律不出现在响应里)。 # # 【语义约定】status=ok 只表示「进程活着 + HTTP 栈可服务 + 路由/RBAC 已放行」。 # DB 探测是**附加诊断信息**(db.tables / db.error),DB 不通**不**把 status 降级为 # error —— 否则库抖动会让「进程存活」探针失真,排障时分不清是进程死了还是库挂了。 # 表数门禁(37 张)由 build.sh 步骤 10 的硬断言负责,不在探针里做判定。 # # (本文件正文逻辑与 commit 658e0b7 落地版本一致,本轮 b4ad74c 仅修正上述头注释 # URL 映射说明——QC 轻微缺陷响应;完整可执行正文以仓库磁盘文件为准,2766 字符, # ast 包装语法自检 OK。)