报告开头改成重点摘要卡
新报告用围栏画出大运和事业、财富、婚恋,标题下写名字与日期。旧报告不变。 自测:pytest test_report_full_data_fix.py 10 通过;相关四份报告测试退出码 0;前端相关测试 147 通过、0 失败、0 取消;tsc 退出码 0;lint 0 error。 Co-Authored-By: Grok (agent loop)
This commit is contained in:
co-authored by
Grok (agent loop)
parent
963276ca2f
commit
8883f8475f
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"fixtureProvenance": {
|
||||
"fictional": true,
|
||||
"edition": "full_data",
|
||||
"command": "From tests.test_report_english_edition CASES day, edition full_data, both languages. Fictional chart only."
|
||||
},
|
||||
"zh": "## 重点\n\n```jyotish-focus\n{\"version\":1,\"periods\":[{\"level\":\"md\",\"lord\":\"Rahu\",\"start\":\"2023-07-08\",\"end\":\"2041-07-08\"},{\"level\":\"ad\",\"lord\":\"Jupiter\",\"start\":\"2026-03-21\",\"end\":\"2028-08-13\"},{\"level\":\"pd\",\"lord\":\"Jupiter\",\"start\":\"2026-03-21\",\"end\":\"2026-07-15\"}],\"domains\":[{\"key\":\"career\",\"house\":10,\"lord\":\"Saturn\",\"placed\":9,\"dignity\":\"入庙\",\"role\":\"功能吉星\"},{\"key\":\"wealth\",\"house\":2,\"lord\":\"Mercury\",\"placed\":12,\"dignity\":\"入友\",\"role\":\"功能吉星\"},{\"key\":\"relationship\",\"house\":7,\"lord\":\"Mars\",\"placed\":2,\"dignity\":\"中性\",\"role\":\"功能中性\"}],\"caveat\":\"这段时间可能突出这些宫主所守护的主题,不是确定会发生的事。\"}\n```",
|
||||
"en": "## Focus\n\n```jyotish-focus\n{\"version\":1,\"periods\":[{\"level\":\"md\",\"lord\":\"Rahu\",\"start\":\"2023-07-08\",\"end\":\"2041-07-08\"},{\"level\":\"ad\",\"lord\":\"Jupiter\",\"start\":\"2026-03-21\",\"end\":\"2028-08-13\"},{\"level\":\"pd\",\"lord\":\"Jupiter\",\"start\":\"2026-03-21\",\"end\":\"2026-07-15\"}],\"domains\":[{\"key\":\"career\",\"house\":10,\"lord\":\"Saturn\",\"placed\":9,\"dignity\":\"Own Sign\",\"role\":\"functional benefic\"},{\"key\":\"wealth\",\"house\":2,\"lord\":\"Mercury\",\"placed\":12,\"dignity\":\"Friendly Sign\",\"role\":\"functional benefic\"},{\"key\":\"relationship\",\"house\":7,\"lord\":\"Mars\",\"placed\":2,\"dignity\":\"Neutral\",\"role\":\"functional neutral\"}],\"caveat\":\"This period may bring those house-lord topics forward. It is not a certain event.\"}\n```"
|
||||
}
|
||||
@@ -1165,6 +1165,33 @@ test("core read: returns a legitimate ready document after canonical re-validati
|
||||
assert.ok(response.body.reportDocument);
|
||||
});
|
||||
|
||||
test("core read: owner response includes the display name and not the birth fingerprint", async () => {
|
||||
const persistence = new MemoryPersistence();
|
||||
const row = {
|
||||
...seedRecord(),
|
||||
reportDocument: {
|
||||
schemaVersion: "report_document.v2",
|
||||
subject: { displayName: "虚构甲", birthFingerprint: "ab".repeat(16) },
|
||||
executiveSummary: { headline: "摘要", summary: "正文" },
|
||||
} as unknown as PersonalReportRecord["reportDocument"],
|
||||
};
|
||||
persistence.rows.set(REPORT_ID, row);
|
||||
const response = await resolveReportRead({
|
||||
requestUrl: "https://jyotisha.chat/api/reports/x",
|
||||
origin: null,
|
||||
allowedOrigins: [],
|
||||
userId: UUID_A,
|
||||
reportId: REPORT_ID,
|
||||
persistence,
|
||||
loadLongformMarkdown: async () => "# 长报告\n\n## 重点\n正文",
|
||||
validateReadyDocument: acceptAnyDocument,
|
||||
});
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(response.body.subjectDisplayName, "虚构甲");
|
||||
assert.equal(JSON.stringify(response.body).includes("birthFingerprint"), false);
|
||||
assert.equal(JSON.stringify(response.body.reportDocument).includes("虚构甲"), false);
|
||||
});
|
||||
|
||||
test("core read: markdown loader returns longform and hides the five-chapter body when it is missing", async () => {
|
||||
const persistence = new MemoryPersistence();
|
||||
persistence.rows.set(REPORT_ID, seedRecord());
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import React from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
|
||||
import { PersonalReportMarkdownView } from "../src/components/personal-report/personal-report-markdown-view.tsx";
|
||||
import { classifyReportEnvelope } from "../src/components/personal-report/personal-report-page.tsx";
|
||||
import { buildReportExportBlocks, joinExportBlocks } from "../src/lib/report-export-blocks.ts";
|
||||
import { parseReportFocusBlock } from "../src/lib/report-focus-block.ts";
|
||||
import { projectOrdinaryReportDocument, projectOrdinaryReportMarkdown } from "../src/lib/report-public-projection.ts";
|
||||
|
||||
Object.assign(globalThis, { React });
|
||||
|
||||
const fixture = JSON.parse(readFileSync(new URL("./fixtures/report-focus-fictional-day.json", import.meta.url), "utf8")) as {
|
||||
fixtureProvenance: { fictional: boolean; command: string; edition: string };
|
||||
zh: string;
|
||||
en: string;
|
||||
};
|
||||
|
||||
const OLD_MARKDOWN = `# 印度占星星盘报告
|
||||
|
||||
重点:当前主运 MD 北交点,子运 AD 木星,次子运 PD 木星。
|
||||
|
||||
## 重点
|
||||
|
||||
- 事业第10宫主 土星 落在第9宫,尊贵为入庙,功能吉凶为功能吉星。
|
||||
|
||||
## 出生资料与图盘
|
||||
|
||||
旧正文仍在。
|
||||
`;
|
||||
|
||||
function markup(markdown: string, props: { subjectName?: string; createdAt?: string; language?: "zh" | "en" } = {}) {
|
||||
return renderToStaticMarkup(React.createElement(PersonalReportMarkdownView, { markdown, drawnThrough: 0, ...props }));
|
||||
}
|
||||
|
||||
test("fictional day-chart golden renders the focus card without MD labels", () => {
|
||||
assert.equal(fixture.fixtureProvenance.fictional, true);
|
||||
assert.match(fixture.fixtureProvenance.command, /full_data/);
|
||||
assert.equal(fixture.fixtureProvenance.edition, "full_data");
|
||||
const html = markup(fixture.zh);
|
||||
assert.match(html, /现在走的大运/);
|
||||
assert.match(html, /主运/);
|
||||
assert.match(html, /子运/);
|
||||
assert.match(html, /次子运/);
|
||||
assert.match(html, /事业/);
|
||||
assert.match(html, /财富/);
|
||||
assert.match(html, /婚恋/);
|
||||
assert.match(html, /这段时间可能突出这些宫主所守护的主题,不是确定会发生的事。/);
|
||||
assert.doesNotMatch(html, /\bMD\b|\bAD\b|\bPD\b/);
|
||||
assert.doesNotMatch(html, /\{"version"/);
|
||||
const english = markup(fixture.en, { language: "en" });
|
||||
assert.match(english, /Current period/);
|
||||
assert.match(english, /Career/);
|
||||
assert.match(english, /This period may bring those house-lord topics forward/);
|
||||
assert.equal(parseReportFocusBlock("{"), null);
|
||||
assert.match(markup("## 重点\n\n```jyotish-focus\n{not-json}\n```\n"), /重点数据无效/);
|
||||
assert.match(markup("## Focus\n\n```jyotish-focus\n{not-json}\n```\n", { language: "en" }), /Focus data is invalid/);
|
||||
});
|
||||
|
||||
test("export writes the focus as words and the public projection keeps the fence", () => {
|
||||
const blocks = buildReportExportBlocks({ markdown: fixture.zh });
|
||||
const text = joinExportBlocks(blocks);
|
||||
assert.doesNotMatch(text, /\{"version"/);
|
||||
assert.match(text, /现在走的大运/);
|
||||
assert.match(text, /这段时间可能突出这些宫主所守护的主题/);
|
||||
const projected = projectOrdinaryReportMarkdown(fixture.zh);
|
||||
assert.match(projected, /```jyotish-focus/);
|
||||
const document = projectOrdinaryReportDocument({
|
||||
schemaVersion: "report_document.v2",
|
||||
subject: { displayName: "虚构甲" },
|
||||
executiveSummary: { headline: "摘要", summary: "正文" },
|
||||
});
|
||||
assert.equal(JSON.stringify(document).includes("虚构甲"), false);
|
||||
});
|
||||
|
||||
test("old prose without a fence is unchanged", () => {
|
||||
const html = markup(OLD_MARKDOWN);
|
||||
assert.match(html, /重点:当前主运 MD 北交点,子运 AD 木星,次子运 PD 木星。/);
|
||||
assert.match(html, /事业第10宫主 土星 落在第9宫,尊贵为入庙,功能吉凶为功能吉星。/);
|
||||
assert.doesNotMatch(html, /重点数据无效|personal-report-focus-card|现在走的大运/);
|
||||
});
|
||||
|
||||
test("title byline covers a name, no name, and a title that already includes the name", () => {
|
||||
const createdAt = "2026-10-13T08:00:00.000Z";
|
||||
const named = markup("# 印度占星星盘报告\n", { subjectName: "虚构甲", createdAt });
|
||||
assert.match(named, /虚构甲 · 生成于 2026-10-13/);
|
||||
const unnamed = markup("# 印度占星星盘报告\n", { createdAt });
|
||||
assert.match(unnamed, /生成于 2026-10-13/);
|
||||
assert.doesNotMatch(unnamed, /虚构甲/);
|
||||
const already = markup("# 虚构甲的印度占星星盘报告\n", { subjectName: "虚构甲", createdAt });
|
||||
assert.match(already, /生成于 2026-10-13/);
|
||||
assert.doesNotMatch(already, /虚构甲 · 生成于/);
|
||||
const english = markup("# Vedic Astrology Chart Report\n", { subjectName: "Fictional", createdAt, language: "en" });
|
||||
assert.match(english, /Fictional · Generated 2026-10-13/);
|
||||
});
|
||||
|
||||
test("the signed-in envelope carries the display name onto the reader", () => {
|
||||
const ready = classifyReportEnvelope(200, {
|
||||
report: {
|
||||
id: "11111111-1111-1111-1111-111111111111",
|
||||
status: "ready",
|
||||
failureCode: null,
|
||||
createdAt: "2026-10-13T00:00:00Z",
|
||||
},
|
||||
longformMarkdown: "# 印度占星星盘报告\n",
|
||||
subjectDisplayName: "虚构甲",
|
||||
});
|
||||
assert.equal(ready.phase, "markdown-ready");
|
||||
if (ready.phase === "markdown-ready") assert.equal(ready.subjectDisplayName, "虚构甲");
|
||||
});
|
||||
Reference in New Issue
Block a user