import * as z from "zod" export const AccessSchema = z.union([ z.object({ token: z.string().regex(/^[A-Za-z0-9_-]{20,64}$/) }), z.object({ variantId: z.string().uuid() }), ]) export type AiAccess = z.infer export const ChatRequestSchema = z.object({ access: AccessSchema, mode: z.enum(["chat", "phone"]), messages: z .array(z.object({ role: z.enum(["user", "assistant"]), content: z.string().trim().min(1).max(2000) })) .min(1) .max(40), }) export const CHANNELS = { instagram: "Instagram", facebook: "Facebook", linkedin: "LinkedIn", google: "Google Ads" } as const export type Channel = keyof typeof CHANNELS export const TONES = ["Locker", "Professionell", "Emotional", "Witzig"] as const export type Tone = (typeof TONES)[number] export const GenerateRequestSchema = z.discriminatedUnion("task", [ z.object({ task: z.literal("email"), access: AccessSchema, inquiry: z.string().trim().min(10).max(4000) }), z.object({ task: z.literal("quote"), access: AccessSchema, inquiry: z.string().trim().min(10).max(4000) }), z.object({ task: z.literal("content"), access: AccessSchema, topic: z.string().trim().min(3).max(500), channel: z.enum(["instagram", "facebook", "linkedin", "google"]), tone: z.enum(TONES), }), ]) export const BookingSchema = z.object({ art: z.string(), name: z.string(), kontakt: z.string(), datum: z.string().optional(), uhrzeit: z.string().optional(), personen: z.string().optional(), anliegen: z.string().optional(), }) export type Booking = z.infer export const QuoteSchema = z.object({ betreff: z.string(), anrede: z.string(), einleitung: z.string(), positionen: z.array( z.object({ titel: z.string(), beschreibung: z.string(), menge: z.number(), einheit: z.string(), einzelpreis: z.number() }) ), hinweise: z.array(z.string()), rueckfragen: z.array(z.string()), gueltig_tage: z.number(), abschluss: z.string(), }) export type Quote = z.infer export const ContentSchema = z.object({ varianten: z.array( z.object({ hook: z.string(), text: z.string(), hashtags: z.array(z.string()), cta: z.string(), bildidee: z.string() }) ), }) export type ContentResult = z.infer // Zeilenweise JSON (NDJSON) von /api/ai/chat und /api/ai/generate (E-Mail) export type AiEvent = | { type: "text"; text: string } | { type: "booking"; data: Booking } | { type: "error"; message: string } | { type: "done" }