Files
GEOAgentArticleOptimizer/src/lib/cases/validation.ts
T
2026-07-08 13:08:12 +08:00

63 lines
1.7 KiB
TypeScript

import { z } from "zod";
import type {
CaseListFilters,
CaseMetadataPatch,
OptimizationCaseStatus,
OptimizationCaseType,
ResultVersionStatus,
} from "./types";
export const caseTypeSchema = z.enum([
"article",
"human_copy",
]) satisfies z.ZodType<OptimizationCaseType>;
export const caseStatusSchema = z.enum([
"running",
"optimized",
"failed",
"archived",
]) satisfies z.ZodType<OptimizationCaseStatus>;
export const resultVersionStatusSchema = z.enum([
"optimized",
"failed",
]) satisfies z.ZodType<ResultVersionStatus>;
const optionalTrimmedText = z
.preprocess((value) => (value == null ? undefined : value), z.string().trim())
.optional();
function booleanQuery(value: unknown) {
if (value === true || value === "true") return true;
if (value === false || value === "false") return false;
return value;
}
export const caseMetadataPatchSchema = z.object({
title: optionalTrimmedText,
customer_name: optionalTrimmedText,
brand_name: optionalTrimmedText,
project_tags: z.array(z.string().trim().min(1)).optional(),
notes: optionalTrimmedText,
}) satisfies z.ZodType<CaseMetadataPatch>;
export const caseListFiltersSchema = z.object({
q: optionalTrimmedText,
case_type: caseTypeSchema.optional(),
status: caseStatusSchema.optional(),
publish_target: optionalTrimmedText,
project_tag: optionalTrimmedText,
created_from: optionalTrimmedText,
created_to: optionalTrimmedText,
include_archived: z.preprocess(booleanQuery, z.boolean().default(false)),
}) satisfies z.ZodType<CaseListFilters>;
export const resultVersionPublicationInputSchema = z.object({
publish_target: z.string().trim().min(1),
url: z.string().trim().url(),
published_at: z.string().datetime(),
notes: z.string().trim().default(""),
});