fix(chart): skip VedAstro on chart-page first paint
Independent Staging Quality Gate / validate (push) Canceled after 2m16s
Independent Staging Quality Gate / publish (push) Canceled after 0s

The natal /api/chart request from the chart page now sends skip_vedastro_main_entry_overview, matching the ephemeris page. Mapper and contract never read that evidence. BUG-718 recurs from BUG-161. Tests lock both foreground natal paths.
This commit is contained in:
jesse-ux
2026-09-16 00:22:00 +08:00
parent ce1939b074
commit 62be52dacf
8 changed files with 99 additions and 3 deletions
+1
View File
@@ -56,6 +56,7 @@ function birthPayload(profile: ChartViewProfileInput): Record<string, unknown> {
ayanamsa: resolveAyanamsa({ ayanamsa: profile.ayanamsa }),
node_mode: "mean",
house_system: "P",
skip_vedastro_main_entry_overview: true,
};
}
+18 -2
View File
@@ -52,8 +52,10 @@ function asResult(path: string, value: EngineCallResult | Record<string, unknown
function engine(overrides: Record<string, EngineCallResult | Record<string, unknown> | null> = {}) {
const calls: string[] = [];
const postEngine: ChartViewEnginePost = async (path) => {
const bodies: Array<{ path: string; body: Record<string, unknown> }> = [];
const postEngine: ChartViewEnginePost = async (path, body) => {
calls.push(path);
bodies.push({ path, body });
if (path in overrides) return asResult(path, overrides[path]!);
if (path === "/api/chart") return asResult(path, golden.chart);
if (path === "/api/varga_full") return asResult(path, golden.varga_full);
@@ -62,7 +64,7 @@ function engine(overrides: Record<string, EngineCallResult | Record<string, unkn
if (path === "/api/qizheng") return asResult(path, null);
return asResult(path, null);
};
return { calls, postEngine };
return { calls, bodies, postEngine };
}
function captureWarnings<T>(run: () => Promise<T>): Promise<{ result: T; warnings: unknown[] }> {
@@ -128,6 +130,20 @@ test("an incomplete birth profile returns a structured message, not 500", async
assert.equal(calls.length, 0);
});
test("foreground chart-view natal requests skip VedAstro overview", async () => {
const { bodies, postEngine } = engine();
await assembleChartView({
userId: "user-1",
profile,
postEngine,
asOf: "2026-09-15",
});
const natal = bodies.filter((item) => item.path === "/api/chart");
assert.equal(natal.length, 1);
assert.equal(natal[0]?.body.skip_vedastro_main_entry_overview, true);
assert.match(loadSource, /skip_vedastro_main_entry_overview:\s*true/);
});
test("opening the natal chart does not call follow-up engine paths", async () => {
const { calls, postEngine } = engine();
const result = await assembleChartView({
+10
View File
@@ -147,6 +147,16 @@ test("the ephemeris BFF does not import billing or mastra", () => {
assert.doesNotMatch(viewSource, /consultation-billing|@\/mastra/);
});
test("ephemeris natal and transit chart requests skip VedAstro overview", () => {
assert.equal((routeSource.match(/skip_vedastro_main_entry_overview:\s*true/g) ?? []).length, 2);
const result = executeRoute({ user: true, row: completeRow });
const chartCalls = result.upstream.filter((item) => item.url.endsWith("/api/chart"));
assert.ok(chartCalls.length >= 2);
for (const call of chartCalls) {
assert.equal(call.body.skip_vedastro_main_entry_overview, true);
}
});
test("unauthenticated ephemeris requests are 401", () => {
const result = executeRoute({ user: false, row: null });
assert.equal(result.status, 401);