128 lines
4.0 KiB
TypeScript
128 lines
4.0 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
// ================================
|
|
// Enums
|
|
// ================================
|
|
|
|
export const ProjectStatusEnum = z.enum(['ACTIVE', 'ARCHIVED'])
|
|
export const LinkTypeEnum = z.enum(['WEBSITE', 'GITHUB', 'HUGGINGFACE', 'PAPER'])
|
|
|
|
// ================================
|
|
// Base Schemas
|
|
// ================================
|
|
|
|
export const ExternalLinkSchema = z.object({
|
|
type: LinkTypeEnum,
|
|
url: z.string()
|
|
.min(1, 'URL is required')
|
|
.max(2000, 'URL is too long')
|
|
.refine((url) => {
|
|
try {
|
|
const parsed = new URL(url)
|
|
return ['http:', 'https:'].includes(parsed.protocol)
|
|
} catch {
|
|
return false
|
|
}
|
|
}, 'URL must use http or https protocol'),
|
|
title: z.string().max(200).optional()
|
|
})
|
|
|
|
export const TagSchema = z.object({
|
|
name: z.string().min(1).max(50),
|
|
nameEn: z.string().max(50).optional()
|
|
})
|
|
|
|
// ================================
|
|
// Project Schemas
|
|
// ================================
|
|
|
|
export const ProjectBaseSchema = z.object({
|
|
name: z.string().min(1).max(200),
|
|
nameEn: z.string().max(200).optional(),
|
|
description: z.string().min(10).max(500),
|
|
descriptionEn: z.string().max(500).optional(),
|
|
content: z.string().max(10000).optional(),
|
|
contentEn: z.string().max(10000).optional(),
|
|
status: ProjectStatusEnum.default('ACTIVE'),
|
|
source: z.string().max(100).optional()
|
|
})
|
|
|
|
export const ProjectInputSchema = ProjectBaseSchema.extend({
|
|
tags: z.array(TagSchema).min(1, 'At least one tag is required').max(10),
|
|
links: z.array(ExternalLinkSchema).min(1, 'At least one link is required').max(10)
|
|
})
|
|
|
|
// ================================
|
|
// Webhook Schemas
|
|
// ================================
|
|
|
|
export const WebhookAuthSchema = z.object({
|
|
apiKey: z.string().min(32, 'Invalid API key format')
|
|
})
|
|
|
|
export const WebhookPayloadSchema = WebhookAuthSchema.extend({
|
|
projects: z.array(ProjectInputSchema).min(1).max(100)
|
|
})
|
|
|
|
// ================================
|
|
// Discovery Task Schemas
|
|
// ================================
|
|
|
|
export const TaskStatusEnum = z.enum(['PENDING', 'IN_PROGRESS', 'COMPLETED', 'FAILED'])
|
|
|
|
export const CreateDiscoveryTaskSchema = WebhookAuthSchema.extend({
|
|
tasks: z.array(z.object({
|
|
sourceUrl: z.string().url().max(2000),
|
|
sourceType: z.string().max(50).default('manual'),
|
|
})).min(1)
|
|
})
|
|
|
|
export const UpdateDiscoveryTaskSchema = z.object({
|
|
apiKey: z.string().min(32),
|
|
status: TaskStatusEnum,
|
|
explorationData: z.record(z.unknown()).optional(),
|
|
explorationSummary: z.string().max(1000).optional(),
|
|
errorMessage: z.string().max(2000).optional(),
|
|
})
|
|
|
|
export const GetDiscoveryTasksQuerySchema = z.object({
|
|
status: TaskStatusEnum.optional(),
|
|
limit: z.coerce.number().int().positive().max(100).default(10),
|
|
offset: z.coerce.number().int().nonnegative().default(0),
|
|
})
|
|
|
|
/**
|
|
* 检查任务去重 Schema
|
|
* 用于在创建任务前检查 URL 是否已存在
|
|
*/
|
|
export const CheckTaskDuplicatesSchema = WebhookAuthSchema.extend({
|
|
urls: z.array(z.string().url().max(2000)).min(1).max(100),
|
|
sourceType: z.string().max(50).optional(),
|
|
})
|
|
|
|
// ================================
|
|
// Query Schemas
|
|
// ================================
|
|
|
|
export const ProjectQuerySchema = z.object({
|
|
search: z.string().min(2).max(100).optional(),
|
|
tags: z.array(z.string()).optional(),
|
|
status: ProjectStatusEnum.optional(),
|
|
page: z.coerce.number().int().positive().default(1),
|
|
limit: z.coerce.number().int().positive().max(100).default(20)
|
|
})
|
|
|
|
// ================================
|
|
// Types
|
|
// ================================
|
|
|
|
export type ExternalLink = z.infer<typeof ExternalLinkSchema>
|
|
export type Tag = z.infer<typeof TagSchema>
|
|
export type ProjectInput = z.infer<typeof ProjectInputSchema>
|
|
export type WebhookPayload = z.infer<typeof WebhookPayloadSchema>
|
|
export type ProjectQuery = z.infer<typeof ProjectQuerySchema>
|
|
export type TaskStatus = z.infer<typeof TaskStatusEnum>
|
|
export type CreateDiscoveryTask = z.infer<typeof CreateDiscoveryTaskSchema>
|
|
export type UpdateDiscoveryTask = z.infer<typeof UpdateDiscoveryTaskSchema>
|
|
export type GetDiscoveryTasksQuery = z.infer<typeof GetDiscoveryTasksQuerySchema>
|