refactor: 移除 AI 词云、AI 时间轴和博客模块
暂停开发以下功能,将设计文档移至未完成计划文件夹: - AI 词云 (Keyword Cloud): 前端、API、数据库模型、n8n 工作流 - AI 时间轴 (AI Timeline): 前端、API、数据库模型 - 博客 (Blog): 导航链接占位 变更内容: - 删除词云和时间轴的前端页面及组件 - 删除 /api/keyword-cloud/* 和 /api/events/* API 端点 - 从 prisma/schema.prisma 移除 Keyword, Quarter, VisualStyleRule, KeywordCloudErrorLog, AIEvent 模型 - 从 validations.ts 移除相关 Zod Schema - 从国际化消息中移除 keywordCloud/timeline 命名空间 - 从导航菜单移除词云、时间轴、博客链接 - 更新 CLAUDE.md 移除词云系统文档 设计文档已移至 .omc/plans/postponed-features/ 供后续恢复开发参考
This commit is contained in:
+23
-115
@@ -145,121 +145,6 @@ export type UpdateDiscoveryTask = z.infer<typeof UpdateDiscoveryTaskSchema>;
|
||||
export type GetDiscoveryTasksQuery = z.infer<typeof GetDiscoveryTasksQuerySchema>;
|
||||
export type BatchResetTasks = z.infer<typeof BatchResetTasksSchema>;
|
||||
|
||||
// ================================
|
||||
// Keyword Cloud Schemas
|
||||
// ================================
|
||||
|
||||
// 视觉配置 Schema
|
||||
const VisualConfigSchema = z.object({
|
||||
color: z.enum(["primary", "secondary", "accent", "gray"]),
|
||||
size: z.enum(["text-5xl", "text-4xl", "text-3xl", "text-2xl", "text-xl", "text-lg", "text-base"]),
|
||||
border: z.enum(["border-4", "border-2"]),
|
||||
rotation: z
|
||||
.string()
|
||||
.regex(/^-?rotate-\d+$/)
|
||||
.nullable()
|
||||
.optional(),
|
||||
});
|
||||
|
||||
// 关键词输入 Schema
|
||||
export const KeywordInputSchema = z.object({
|
||||
word: z.string().min(1).max(100),
|
||||
trendScore: z.number().int().min(0).max(100),
|
||||
description: z.string().min(10).max(500),
|
||||
descriptionEn: z.string().max(500).optional(),
|
||||
detailPoints: z.array(z.string().min(5).max(100)).min(1).max(5),
|
||||
detailPointsEn: z.array(z.string().max(100)).max(5).optional(),
|
||||
visualConfig: VisualConfigSchema,
|
||||
});
|
||||
|
||||
// 批量写入关键词请求 Schema
|
||||
export const BatchKeywordsRequestSchema = z.object({
|
||||
quarter: z.string().regex(/^\d{4}-Q[1-4]$/, "格式应为 YYYY-QN"),
|
||||
keywords: z.array(KeywordInputSchema).min(1).max(50),
|
||||
});
|
||||
|
||||
// 季度 Schema
|
||||
export const QuarterSchema = z.object({
|
||||
quarter: z.string().regex(/^\d{4}-Q[1-4]$/),
|
||||
title: z.string().min(1).max(200),
|
||||
titleEn: z.string().max(200).optional(),
|
||||
subtitle: z.string().max(500).optional(),
|
||||
subtitleEn: z.string().max(500).optional(),
|
||||
displayOrder: z.number().int().min(0).default(0),
|
||||
isActive: z.boolean().default(true),
|
||||
});
|
||||
|
||||
// 视觉规则 Schema
|
||||
export const VisualStyleRuleSchema = z
|
||||
.object({
|
||||
name: z.string().min(1).max(100),
|
||||
minScore: z.number().int().min(0).max(100),
|
||||
maxScore: z.number().int().min(0).max(100),
|
||||
color: z.enum(["primary", "secondary", "accent", "gray"]),
|
||||
size: z.enum([
|
||||
"text-5xl",
|
||||
"text-4xl",
|
||||
"text-3xl",
|
||||
"text-2xl",
|
||||
"text-xl",
|
||||
"text-lg",
|
||||
"text-base",
|
||||
]),
|
||||
border: z.enum(["border-4", "border-2"]),
|
||||
rotation: z
|
||||
.string()
|
||||
.regex(/^-?rotate-\d+$/)
|
||||
.nullable()
|
||||
.optional(),
|
||||
priority: z.number().int().min(0).default(0),
|
||||
enabled: z.boolean().default(true),
|
||||
})
|
||||
.refine((data) => data.minScore < data.maxScore, {
|
||||
message: "minScore 必须小于 maxScore",
|
||||
});
|
||||
|
||||
// API 响应 Schema
|
||||
export const KeywordCloudResponseSchema = z.object({
|
||||
success: z.boolean(),
|
||||
data: z.any().optional(),
|
||||
error: z.string().optional(),
|
||||
});
|
||||
|
||||
// ================================
|
||||
// AI Timeline Schemas
|
||||
// ================================
|
||||
|
||||
export const AIEventInputSchema = z.object({
|
||||
title: z.string().min(1).max(200),
|
||||
titleEn: z.string().max(200).optional(),
|
||||
eventDate: z.string().datetime(),
|
||||
description: z.string().min(10).max(500),
|
||||
descriptionEn: z.string().max(500).optional(),
|
||||
imageUrl: z.string().url(),
|
||||
sourceUrl: z.string().url().optional(),
|
||||
});
|
||||
|
||||
export const AIEventQuerySchema = z.object({
|
||||
year: z
|
||||
.string()
|
||||
.regex(/^\d{4}$/)
|
||||
.optional(),
|
||||
limit: z.string().regex(/^\d+$/).transform(Number).optional(),
|
||||
offset: z.string().regex(/^\d+$/).transform(Number).optional(),
|
||||
});
|
||||
|
||||
// ================================
|
||||
// Types
|
||||
// ================================
|
||||
|
||||
export type KeywordInput = z.infer<typeof KeywordInputSchema>;
|
||||
export type BatchKeywordsRequest = z.infer<typeof BatchKeywordsRequestSchema>;
|
||||
export type Quarter = z.infer<typeof QuarterSchema>;
|
||||
export type VisualStyleRule = z.infer<typeof VisualStyleRuleSchema>;
|
||||
export type AIEventInput = z.infer<typeof AIEventInputSchema>;
|
||||
export type AIEventQuery = z.infer<typeof AIEventQuerySchema>;
|
||||
export type KeywordCloudResponse = z.infer<typeof KeywordCloudResponseSchema>;
|
||||
|
||||
// ================================
|
||||
// Tags API Schemas
|
||||
// ================================
|
||||
@@ -344,6 +229,26 @@ export const TagMaintenanceRequestSchema = z.object({
|
||||
});
|
||||
});
|
||||
|
||||
export const TagMatchCandidateSchema = z.object({
|
||||
name: z.string().min(1, "Tag name is required").max(100),
|
||||
nameEn: z.string().max(100).optional(),
|
||||
});
|
||||
|
||||
export const TagMatchAvailableTagSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
name: z.string().min(1).max(100),
|
||||
nameEn: z.string().max(100).nullable().optional(),
|
||||
slug: z.string().max(150).optional(),
|
||||
projectCount: z.number().int().nonnegative().optional(),
|
||||
});
|
||||
|
||||
export const TagMatchRequestSchema = z.object({
|
||||
apiKey: z.string().min(32, "Invalid API key format"),
|
||||
candidates: z.array(TagMatchCandidateSchema).min(1).max(30),
|
||||
availableTags: z.array(TagMatchAvailableTagSchema).max(1000).optional(),
|
||||
limit: z.number().int().min(1).max(10).default(5),
|
||||
});
|
||||
|
||||
// ================================
|
||||
// Types
|
||||
// ================================
|
||||
@@ -352,3 +257,6 @@ export type TagUpdate = z.infer<typeof TagUpdateSchema>;
|
||||
export type MergeTarget = z.infer<typeof MergeTargetSchema>;
|
||||
export type TagMerge = z.infer<typeof TagMergeSchema>;
|
||||
export type TagMaintenanceRequest = z.infer<typeof TagMaintenanceRequestSchema>;
|
||||
export type TagMatchCandidate = z.infer<typeof TagMatchCandidateSchema>;
|
||||
export type TagMatchAvailableTag = z.infer<typeof TagMatchAvailableTagSchema>;
|
||||
export type TagMatchRequest = z.infer<typeof TagMatchRequestSchema>;
|
||||
|
||||
Reference in New Issue
Block a user