mirror of
https://github.com/Since-3/since3-portal.git
synced 2026-10-12 19:51:17 +00:00
77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
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<typeof AccessSchema>
|
|
|
|
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<typeof BookingSchema>
|
|
|
|
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<typeof QuoteSchema>
|
|
|
|
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<typeof ContentSchema>
|
|
|
|
// 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" }
|