import assert from "node:assert/strict"; import test from "node:test"; import { callScriptSchema, emailDraftSchema, emailSubjectSchema, followUpDraftSchema, auditSummarySchema, qualityReviewSchema, publicAuditTextSchema, internalFindingsSchema, type CallScript, type EmailDraft, type EmailSubject, type FollowUpDraft, type AuditSummary, type PublicAuditText, type QualityReview, type InternalFindings, } from "../lib/ai/schemas"; test("internal findings schema accepts task-focused evidence", () => { const parsed = internalFindingsSchema.parse({ findings: [ { section: "UX", finding: "Landingpage is not responsive on mobile viewport.", suggestion: "Add responsive breakpoints for cards and typography.", }, ], summary: "One high-priority UX gap was found.", }); assert.equal(parsed.findings.length, 1); assert.equal(parsed.findings[0].section, "UX"); }); test("audit summary and public text schemas remain intentionally lightweight", () => { const summaryParsed = auditSummarySchema.parse({ summary: "Kurze Zusammenfassung mit den wichtigsten Verbesserungen.", keyFindings: ["Fehlende Kontaktmöglichkeit.", "Langsame Ladezeiten."], }); const publicParsed = publicAuditTextSchema.parse({ publicText: "Dein Shop ist sauber, aber der erste Eindruck lässt Potenzial erkennen.", }); assert.equal(summaryParsed.keyFindings.length, 2); assert.equal(typeof publicParsed.publicText, "string"); }); test("outreach schemas parse German customer-facing payloads", () => { const emailDraftParsed = emailDraftSchema.parse({ body: "Hallo, ich habe mir euer Angebot angesehen...", }); const subjectParsed = emailSubjectSchema.parse({ subject: "Kurznotiz zu eurem Webauftritt", }); const callParsed = callScriptSchema.parse({ openingLine: "Guten Tag, ich bin ...", callScript: [ "Euer Fokus auf Terminbuchung ist stark.", "Wie läuft eure aktuelle Lead-Generierung?", ], closeLine: "Ich schicke im Anschluss kurz die wichtigsten Beobachtungen.", }); const followParsed = followUpDraftSchema.parse({ message: "Kurzer Follow-up-Hinweis für nächste Woche.", followInDays: 4, goals: ["Antwort auf Rückmeldung erhalten"], }); const qualityParsed = qualityReviewSchema.parse({ isValid: true, issues: [], suggestions: ["Mehr Kundennutzen konkret beschreiben."], }); assert.equal(typeof emailDraftParsed.body, "string"); assert.equal(typeof subjectParsed.subject, "string"); assert.equal(Array.isArray(callParsed.callScript), true); assert.equal(typeof followParsed.message, "string"); assert.equal(Array.isArray(qualityParsed.suggestions), true); }); test("schema-inferred types are exported for Convex action wiring", () => { const typedFindings: InternalFindings = { findings: [ { section: "Homepage", finding: "No visible Datenschutzhinweis.", suggestion: "Bitte Hinweis ergänzen.", }, ], summary: "One finding identified.", }; const typedSummary: AuditSummary = { summary: "Kernbefund mit 2 Punkten.", keyFindings: ["Kontaktseite fehlt."], }; const typedPublicText: PublicAuditText = { publicText: "Starker Start, aber optimierungsfähig.", }; const typedEmail: EmailDraft = { body: "Text mit Ich-Perspektive und konkretem Vorschlag.", }; const typedSubject: EmailSubject = { subject: "Kurzer Betreff", }; const typedCall: CallScript = { openingLine: "Hallo, ich habe euer Shop geprüft.", callScript: ["Wie gehen die Leads aktuell rein?"], closeLine: "Ich melde mich nach der Rückfrage erneut.", }; const typedFollowUp: FollowUpDraft = { message: "Kurzes Follow-up ohne harte Floskel.", }; const typedQuality: QualityReview = { isValid: true, issues: [], suggestions: [], }; assert.equal(typedFindings.findings.length, 1); assert.equal(typedSummary.keyFindings.length, 1); assert.equal(typedPublicText.publicText.length > 0, true); assert.equal(typeof typedEmail.body, "string"); assert.equal(typeof typedSubject.subject, "string"); assert.equal(typedCall.callScript.length, 1); assert.equal(typedFollowUp.message.length > 0, true); assert.equal(typedQuality.isValid, true); });