feat: 搭建阶段 0 与阶段 1 基础工程

This commit is contained in:
2026-04-02 16:28:44 +08:00
parent 02ec7c3a03
commit a5b079a673
37 changed files with 7379 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
import {
confidenceLevels,
evidenceSourceTypes,
executionStatuses,
platforms,
reportableTaskStatuses,
sampleFlags
} from "@cross-ai/domain";
import { z } from "zod";
export const SourceScopeSchema = z.object({
platforms: z.array(z.enum(platforms)).min(1),
link_count: z.number().int().nonnegative(),
review_count: z.number().int().nonnegative()
});
export const InsightCardSchema = z
.object({
card_id: z.string().min(1),
title: z.string().min(1),
statement: z.string().min(1),
confidence: z.enum(confidenceLevels),
sample_flag: z.enum(sampleFlags),
source_scope: SourceScopeSchema,
evidence_ids: z.array(z.string().min(1))
})
.superRefine((value, ctx) => {
if (value.sample_flag !== "insufficient" && value.evidence_ids.length === 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Non-insufficient insights must include evidence_ids.",
path: ["evidence_ids"]
});
}
});
export const EvidenceSchema = z.object({
evidence_id: z.string().min(1),
platform: z.enum(platforms),
source_type: z.enum(evidenceSourceTypes),
source_url: z.string().url(),
review_ref: z.string().nullable(),
snippet: z.string().min(1),
captured_at: z.string().datetime()
});
export const PlatformInsightSchema = z.object({
platform: z.enum(platforms),
execution_status: z.enum(executionStatuses),
selected_link_count: z.number().int().nonnegative(),
price_range: z
.object({
min: z.number().nonnegative(),
max: z.number().nonnegative()
})
.nullable(),
selling_points: z.array(InsightCardSchema),
positive_themes: z.array(InsightCardSchema),
negative_themes: z.array(InsightCardSchema),
store_diff_notes: z.array(InsightCardSchema)
});
export const ReportSchema = z.object({
report_id: z.string().min(1),
report_version: z.number().int().positive(),
task_id: z.string().min(1),
generated_at: z.string().datetime(),
task_status: z.enum(reportableTaskStatuses),
summary: z.object({
headline: z.string().min(1),
key_points: z.array(z.string().min(1)).min(1),
limitations: z.array(z.string().min(1))
}),
product_snapshot: z.object({
query: z.string().min(1),
normalized_product_name: z.string().min(1),
platform_count: z.number().int().nonnegative(),
selected_link_count: z.number().int().nonnegative(),
review_sample_count: z.number().int().nonnegative(),
analysis_time_range: z.object({
start: z.string().datetime(),
end: z.string().datetime()
})
}),
platform_insights: z.array(PlatformInsightSchema),
cross_platform_insights: z.array(InsightCardSchema),
recommendations: z.array(InsightCardSchema),
evidence_index: z.array(EvidenceSchema),
quality_flags: z.object({
sample_insufficient: z.boolean(),
partial_platform_failure: z.boolean(),
blocked_platforms: z.array(z.enum(platforms)),
failed_platforms: z.array(z.enum(platforms))
})
});
export type ReportSnapshot = z.infer<typeof ReportSchema>;
export function parseReportSnapshot(input: unknown): ReportSnapshot {
return ReportSchema.parse(input);
}