给别人出报告能读到档案,对话和报告标明 AI 生成

BUG-1063:后台按列只读档案,授权前数据库拒绝读表,授权后通过。对话输入框下和报告标题下加上 AI 生成说明。状态板按已部署提交改措辞,不标 resolved。下载文件元数据没有做。

自测:tsc 退出码 0;lint 0 error;定向测试 51 通过;test:db 82 项里 13 项为 Windows 已知失败,无新增;隐私标记退出码 0。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-10-14 09:30:51 +08:00
co-authored by Grok (agent loop)
parent f4c53e7f9f
commit fca62fda43
16 changed files with 376 additions and 39 deletions
+7
View File
@@ -1850,6 +1850,7 @@ section[popover]:has(> [data-sonner-toaster]), section[popover][aria-label^="页
outline-offset: 3px;
}
.composer { width: min(760px, 100%); display: flex; flex-direction: column; gap: var(--space-2); margin: 0 auto; border: 1px solid var(--color-border-strong); transition: border-color 140ms ease-out; padding: var(--space-3) var(--space-3) var(--space-2); border-radius: var(--radius-lg); background: var(--color-canvas); }
.composer-ai-notice { width: min(760px, 100%); margin: var(--space-2) auto 0; overflow: hidden; color: var(--color-ink-tertiary); font-size: var(--type-overline); line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
/* The composer's own bottom row. It replaces .composer-footer, a strip below
the composer that held a permanent 44px whether or not it had anything to
show. The row only exists when there is a toolbar or a count to render. */
@@ -4352,6 +4353,12 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class
font-size: var(--type-caption);
line-height: 1.5;
}
.personal-report-ai-notice {
margin: 0 0 var(--space-3);
color: var(--color-ink-tertiary);
font-size: var(--type-overline);
line-height: 1.45;
}
.personal-report-focus-card {
display: grid;
gap: var(--space-3);
@@ -12,6 +12,7 @@ import {
serverComposerDraftSnapshot,
subscribeComposerDraft,
} from "@/lib/composer-draft";
import { CHAT_AI_NOTICE_ZH } from "@/lib/ai-generated-notice";
import { COMPOSER_QUEUE_LABEL, COMPOSER_QUEUE_RECALL_LABEL } from "@/lib/queued-draft";
export const composerRemainingId = "composer-character-remaining";
@@ -133,6 +134,7 @@ export function ChatComposer({
</div>
</div>
</form>
<p className="composer-ai-notice">{CHAT_AI_NOTICE_ZH}</p>
</>
);
}
@@ -25,6 +25,7 @@ import {
type ReportDocument,
type ReportDocumentV2,
} from "@/lib/personal-report-contract";
import { reportAiNotice } from "@/lib/ai-generated-notice";
import { reportThemeLabel } from "@/lib/personal-report-progress";
const CLAIM_STATUS_LABELS: Record<ClaimStatus, string> = {
@@ -191,6 +192,7 @@ function ReportCover({ document, d1 }: { document: ReportDocument; d1: ChartV1 |
<div>
<p className="personal-report-kicker">个人报告</p>
<h1>{document.subject.displayName}</h1>
<p className="personal-report-ai-notice">{reportAiNotice("zh")}</p>
<p className="personal-report-deck">{document.executiveSummary.headline}</p>
</div>
<dl className="personal-report-metadata">
@@ -12,6 +12,7 @@ import {
parseReportChartBlock,
toNorthIndianChart,
} from "@/lib/report-chart-block";
import { reportAiNotice } from "@/lib/ai-generated-notice";
import { parseReportFocusBlock, reportTitleByline } from "@/lib/report-focus-block";
import { reportChartGrid } from "@/lib/report-chart-grid-rehype";
import { NorthIndianChartSvg } from "@/components/personal-report/vedic-chart-svg";
@@ -69,10 +70,12 @@ function markdownComponents(
h1: ({ children }) => {
const title = flattenText(children).trim();
const line = byline.shown ? null : reportTitleByline({ title, subjectName, createdAt, language });
const notice = byline.shown ? null : reportAiNotice(language);
byline.shown = true;
return (
<>
<h1>{children}</h1>
{notice ? <p className="personal-report-ai-notice">{notice}</p> : null}
{line ? <p className="personal-report-md-byline">{line}</p> : null}
</>
);
+14
View File
@@ -0,0 +1,14 @@
import type { ReportLanguage } from "./report-language.ts";
/** Visible label under the chat field. The product shell is Chinese. */
export const CHAT_AI_NOTICE_ZH = "回答由 AI 生成,仅供参考,不构成医疗、法律或投资建议。";
/** English equivalent, locked for a future English shell. Not shown in the Chinese UI. */
export const CHAT_AI_NOTICE_EN = "AI-generated. For reference only; not medical, legal or financial advice.";
export const REPORT_AI_NOTICE_ZH = "本报告由 AI 生成,仅供参考。";
export const REPORT_AI_NOTICE_EN = "This report is AI-generated and for reference only.";
export function reportAiNotice(language: ReportLanguage): string {
return language === "en" ? REPORT_AI_NOTICE_EN : REPORT_AI_NOTICE_ZH;
}