fix: harden AI analysis and seed defaults

This commit is contained in:
2026-07-08 04:38:22 -07:00
parent 9a437f4cbf
commit 6a1add3422
15 changed files with 653 additions and 167 deletions

View File

@@ -0,0 +1,64 @@
import { describe, expect, it, vi } from "vitest";
import { validateElderAiAnalysisOutput, validateKnowledgeEntryInput } from "@/modules/ai/types";
import {
DEFAULT_AI_KNOWLEDGE_ENTRIES,
DEFAULT_PREPARED_AI_ANALYSES,
} from "@/modules/core/server/default-workspace-data";
const FORBIDDEN_DEMO_WORDING_PATTERN = /mock|simulation|simulated|demo|sample|placeholder|fixture|fake|test data|模拟|仿真|演示|样例|示例|占位|测试数据/i;
vi.mock("server-only", () => ({}));
vi.mock("@/modules/core/server/db", () => ({
getDatabase: vi.fn(),
}));
describe("default AI workspace seed data", () => {
it("keeps user-visible AI knowledge content realistic and validator-ready", () => {
expect(DEFAULT_AI_KNOWLEDGE_ENTRIES.length).toBeGreaterThanOrEqual(3);
const scopes = new Set(DEFAULT_AI_KNOWLEDGE_ENTRIES.map((entry) => entry.scope));
expect(scopes).toEqual(new Set(["platform", "organization"]));
for (const entry of DEFAULT_AI_KNOWLEDGE_ENTRIES) {
expect(validateKnowledgeEntryInput(entry)).toEqual({ success: true, input: entry });
expect(entry.status).toBe("enabled");
expect(entry.body.length).toBeGreaterThan(80);
expect([entry.title, entry.category, entry.tags, entry.body].join("\n")).not.toMatch(FORBIDDEN_DEMO_WORDING_PATTERN);
}
});
it("provides completed elder AI analyses that current validators can display", () => {
expect(DEFAULT_PREPARED_AI_ANALYSES.length).toBeGreaterThanOrEqual(1);
for (const analysis of DEFAULT_PREPARED_AI_ANALYSES) {
const validated = validateElderAiAnalysisOutput(analysis.result);
expect(validated).toEqual(analysis.result);
expect(analysis.elderName).toBeTruthy();
expect(analysis.dataScopes).toContain("elder");
expect(analysis.dataScopes).toContain("knowledge");
expect(analysis.createdHoursAgo).toBeGreaterThan(0);
expect(analysis.result.citations.length).toBeGreaterThan(0);
expect(analysis.result.keyFindings.length).toBeGreaterThan(0);
expect(analysis.result.recommendations.length).toBeGreaterThan(0);
expect(JSON.stringify(analysis)).not.toMatch(FORBIDDEN_DEMO_WORDING_PATTERN);
}
});
it("keeps every prepared analysis citation reference displayable", () => {
for (const analysis of DEFAULT_PREPARED_AI_ANALYSES) {
const citationIds = new Set(analysis.result.citations.map((citation) => citation.id));
const referencedIds = [
...analysis.result.keyFindings.flatMap((finding) => finding.citationIds),
...analysis.result.recommendations.flatMap((recommendation) => recommendation.citationIds),
];
expect(referencedIds.length).toBeGreaterThan(0);
expect(new Set(referencedIds)).toEqual(citationIds);
for (const citationId of referencedIds) {
expect(citationIds.has(citationId)).toBe(true);
}
}
});
});