diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index d1307c3d..8fd835b6 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -5195,3 +5195,19 @@ - 复发自:BUG-339(盘面入口 effect 同步 setState;点选卡与快照加载又写了同一模式) - 修复版本:a4ab229e +## BUG-344 | 声明窗口模式未收窄本命类型,staging publish 镜像构建失败 + +- 状态:resolved +- 首次发现:2026-08-21 +- 最近更新:2026-08-21 +- 影响面:Gitea `backend-quality-gate` `publish`、`consultation-route-service.serverChartFromProfile`、`isNatalMinuteConsultationMode` +- 用户现象:run `2029` `validate` 12 分钟通过,`publish` 在 `npm run build` 失败,镜像未发。站点仍停在 `e7f4030e`。 +- 触发条件:staging push 的 publish 镜像构建跑 `next build`。validate 对 staging push 跳过 production build。 +- 根因:BUG-341 给 `ConsultationBirthTimeMode` 增加了 `declared_birth_window`,但 `isNatalMinuteConsultationMode` 仍返回 `boolean`,TypeScript 无法收窄成 `verified_chart | unverified_birth_time`,`serverChartFromProfile` 在 `next build` 报 TS2345。 +- 修复:把该函数改成 `mode is NatalMinuteConsultationMode` 类型谓词。 +- 验证:`frontend/tests/consultation-birth-time-mode.test.ts`;本地 `tsc --noEmit` 通过。 +- 防复发:本命分钟模式判定必须是类型谓词。新增咨询模式时不得把窗口/百科模式传入 `serverChartFromProfile`。staging push 的类型错误只会在 publish 的 `next build` 暴露。 +- 相关记录:BUG-341、BUG-343 +- 复发自:BUG-341(第三条咨询路径扩大了 mode 联合类型,未改类型谓词) +- 修复版本:pending + diff --git a/frontend/src/lib/consultation-birth-time-mode.ts b/frontend/src/lib/consultation-birth-time-mode.ts index 3ab6f7fb..e9e4e478 100644 --- a/frontend/src/lib/consultation-birth-time-mode.ts +++ b/frontend/src/lib/consultation-birth-time-mode.ts @@ -12,10 +12,16 @@ export const consultationBirthTimeModeSchema = z.enum([ ]); export type ConsultationBirthTimeMode = z.infer; +export type NatalMinuteConsultationMode = Extract< + ConsultationBirthTimeMode, + "verified_chart" | "unverified_birth_time" +>; export const UNVERIFIED_BIRTH_TIME_NOTICE = "使用未校正填报时间;分钟敏感结论的置信度已降低。"; -export function isNatalMinuteConsultationMode(mode: ConsultationBirthTimeMode): boolean { +export function isNatalMinuteConsultationMode( + mode: ConsultationBirthTimeMode, +): mode is NatalMinuteConsultationMode { return mode === "verified_chart" || mode === "unverified_birth_time"; } diff --git a/frontend/tests/consultation-birth-time-mode.test.ts b/frontend/tests/consultation-birth-time-mode.test.ts index ae4f3c86..d820eeb0 100644 --- a/frontend/tests/consultation-birth-time-mode.test.ts +++ b/frontend/tests/consultation-birth-time-mode.test.ts @@ -13,6 +13,11 @@ import { getGeneralJyotishAgent } from "../src/mastra/index.ts"; import type { ResolvedLanguageModel } from "../src/mastra/model.ts"; test("general-no-birth-time is an explicit server mode that never runs a chart workflow", () => { + const source = readFileSync(new URL("../src/lib/consultation-birth-time-mode.ts", import.meta.url), "utf8"); + assert.match( + source, + /export function isNatalMinuteConsultationMode\(\s*mode: ConsultationBirthTimeMode,\s*\): mode is NatalMinuteConsultationMode/, + ); assert.equal(consultationBirthTimeModeSchema.safeParse("verified_chart").success, true); assert.equal(consultationBirthTimeModeSchema.safeParse("unverified_birth_time").success, true); assert.equal(consultationBirthTimeModeSchema.safeParse("declared_birth_window").success, true);