fix(report): stop listing reports via PostgREST JSON paths (BUG-574)
Staging PostgREST rejects the executiveSummary JSON-path alias, so GET /api/reports 500s. Persist a plain card_summary column from the Markdown excerpt instead. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,7 +4,10 @@ import {
|
||||
REPORT_DOCUMENT_V2_SCHEMA_VERSION,
|
||||
type ReportDocumentV2,
|
||||
} from "./personal-report-contract.ts";
|
||||
import { extractLongformSummary } from "./personal-report-longform-outline.ts";
|
||||
import {
|
||||
PERSONAL_REPORT_CARD_SUMMARY_MAX_CHARS,
|
||||
extractLongformSummary,
|
||||
} from "./personal-report-longform-outline.ts";
|
||||
import type { PersonalReportRecord } from "./personal-report-service-core.ts";
|
||||
|
||||
type CoverSkillSnapshot = Readonly<{
|
||||
@@ -52,7 +55,7 @@ function coverHouses(): ReportDocumentV2["charts"][number]["houses"] {
|
||||
}
|
||||
|
||||
export function buildLongformCoverDocument(input: LongformCoverInput): ReportDocumentV2 {
|
||||
const summary = extractLongformSummary(input.markdown);
|
||||
const summary = extractLongformSummary(input.markdown, PERSONAL_REPORT_CARD_SUMMARY_MAX_CHARS);
|
||||
const skillName = input.skillSnapshot?.name ?? input.report.skillName;
|
||||
const skillVersion = input.skillSnapshot?.version ?? input.report.skillVersion;
|
||||
const skillSnapshotSha256 = input.skillSnapshot?.sha256 ?? input.report.skillSnapshotSha256;
|
||||
|
||||
@@ -23,6 +23,9 @@ export type LongformOutline = Readonly<{
|
||||
const EAGER_H2 = /成品阅读导航|质量验收矩阵/;
|
||||
const SUMMARY_TITLE = /^(?:解读摘要|摘要)$/;
|
||||
|
||||
/** Dedicated `personal_reports.card_summary` column length. */
|
||||
export const PERSONAL_REPORT_CARD_SUMMARY_MAX_CHARS = 500;
|
||||
|
||||
export function slugifyHeading(title: string, used: Map<string, number>): string {
|
||||
const base = title
|
||||
.trim()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Operational log reason for unknown catch values.
|
||||
*
|
||||
* PostgREST / supabase-js may throw a plain object with `code` and `hint`
|
||||
* instead of an Error instance. Never include message, details, or row data.
|
||||
*/
|
||||
export function sanitizedErrorReason(error: unknown): string {
|
||||
const record = error !== null && typeof error === "object"
|
||||
? error as Record<string, unknown>
|
||||
: null;
|
||||
const name = error instanceof Error && error.name.trim()
|
||||
? error.name.trim()
|
||||
: typeof record?.name === "string" && record.name.trim()
|
||||
? record.name.trim()
|
||||
: "UnknownError";
|
||||
const code = typeof record?.code === "string" ? record.code.trim() : "";
|
||||
const hint = typeof record?.hint === "string" ? record.hint.trim() : "";
|
||||
if (!code && !hint) return name;
|
||||
return `${name} code=${code || "none"} hint=${hint || "none"}`;
|
||||
}
|
||||
Reference in New Issue
Block a user