Files
webdev-pipeline/lib/ai/schemas.ts

158 lines
4.9 KiB
TypeScript

import { z } from "zod";
const nonEmptyTextSchema = z.string().trim().min(1);
export const legacyFindingItemSchema = z.object({
section: z.string(),
finding: z.string(),
suggestion: z.string(),
});
export const v3FindingItemSchema = z.object({
skill_id: nonEmptyTextSchema,
observation: nonEmptyTextSchema,
customer_benefit: nonEmptyTextSchema,
public_phrasing: nonEmptyTextSchema,
severity: z.union([z.literal(1), z.literal(2), z.literal(3)]),
evidence: nonEmptyTextSchema,
applies: z.boolean(),
});
export const findingItemSchema = legacyFindingItemSchema;
export const auditFindingEvidenceRefSchema = z.object({
id: nonEmptyTextSchema,
type: z.enum([
"crawl_page",
"technical_check",
"screenshot",
"pagespeed",
"jina_excerpt",
"generation_stage",
]),
label: nonEmptyTextSchema,
sourceUrl: z.string().trim(),
});
export const auditSpecialistFindingSchema = z
.object({
skillId: nonEmptyTextSchema,
claim: nonEmptyTextSchema,
recommendation: nonEmptyTextSchema,
customerBenefit: nonEmptyTextSchema,
severity: z.union([z.literal(1), z.literal(2), z.literal(3)]),
confidence: z.number().min(0).max(1),
evidenceRefs: z.array(auditFindingEvidenceRefSchema).min(1),
applies: z.boolean(),
unknowns: z.array(z.string()),
})
.superRefine((finding, ctx) => {
const combined = [
finding.claim,
finding.recommendation,
finding.customerBenefit,
].join(" ");
if (/\bunbekannt\b|\bunknown\b/i.test(combined)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "unknown-only findings are not valid audit claims",
path: ["claim"],
});
}
});
export const auditSpecialistResultSchema = z.object({
status: z.enum(["success", "partial", "skipped", "failed"]),
findings: z.array(auditSpecialistFindingSchema),
notes: z.array(z.string()),
});
export const auditRejectedFindingSchema = z.object({
findingId: nonEmptyTextSchema,
skillId: nonEmptyTextSchema,
claim: nonEmptyTextSchema,
rejectionReason: nonEmptyTextSchema,
});
export const auditEvidenceVerificationSchema = z.object({
verifiedFindingIds: z.array(nonEmptyTextSchema),
rejectedFindings: z.array(auditRejectedFindingSchema),
contradictions: z.array(z.string()),
notes: z.array(z.string()),
});
export const internalFindingsSchema = z.object({
findings: z.array(findingItemSchema),
summary: z.string(),
});
export const auditClassificationSchema = z.object({
findings: z.array(v3FindingItemSchema).min(1),
summary: nonEmptyTextSchema,
usedSkills: z.array(nonEmptyTextSchema).nullable(),
});
export const auditGenerationResultSchema = z.object({
findings: z.array(v3FindingItemSchema).min(1),
usedSkills: z.array(nonEmptyTextSchema).min(1),
publicAuditText: nonEmptyTextSchema,
finalSummary: nonEmptyTextSchema,
emailSubject: nonEmptyTextSchema,
emailBody: nonEmptyTextSchema,
phoneScript: nonEmptyTextSchema,
ctaType: z.enum(["anruf", "termin", "rueckruf"]),
});
export const auditSummarySchema = z.object({
summary: z.string(),
keyFindings: z.array(z.string()),
});
export const publicAuditTextSchema = z.object({
publicText: z.string(),
});
export const emailDraftSchema = z.object({
body: z.string(),
});
export const emailSubjectSchema = z.object({
subject: z.string(),
});
export const callScriptSchema = z.object({
openingLine: z.string(),
callScript: z.array(z.string()),
closeLine: z.string(),
});
export const followUpDraftSchema = z.object({
message: z.string(),
followInDays: z.number().int().min(0).nullable(),
goals: z.array(z.string()).nullable(),
});
export const qualityReviewSchema = z.object({
isValid: z.boolean(),
issues: z.array(z.string()),
suggestions: z.array(z.string()),
notes: z.array(z.string()).nullable(),
});
export type FindingItem = z.infer<typeof findingItemSchema>;
export type V3FindingItem = z.infer<typeof v3FindingItemSchema>;
export type AuditFindingEvidenceRef = z.infer<typeof auditFindingEvidenceRefSchema>;
export type AuditSpecialistFinding = z.infer<typeof auditSpecialistFindingSchema>;
export type AuditSpecialistResult = z.infer<typeof auditSpecialistResultSchema>;
export type AuditEvidenceVerification = z.infer<typeof auditEvidenceVerificationSchema>;
export type InternalFindings = z.infer<typeof internalFindingsSchema>;
export type AuditClassification = z.infer<typeof auditClassificationSchema>;
export type AuditGenerationResult = z.infer<typeof auditGenerationResultSchema>;
export type AuditSummary = z.infer<typeof auditSummarySchema>;
export type PublicAuditText = z.infer<typeof publicAuditTextSchema>;
export type EmailDraft = z.infer<typeof emailDraftSchema>;
export type EmailSubject = z.infer<typeof emailSubjectSchema>;
export type CallScript = z.infer<typeof callScriptSchema>;
export type FollowUpDraft = z.infer<typeof followUpDraftSchema>;
export type QualityReview = z.infer<typeof qualityReviewSchema>;