FE_Dev / schema /theme-extraction.ts
GitHub Actions
Deploy from GitHub Actions [dev] - 2025-10-31 07:28:50
68f7925
import { z } from 'zod';
/**
* テーマ抽出リクエストスキーマ
*/
export const themeExtractionRequestSchema = z.object({
url: z.string().url('有効なURLを入力してください'),
provider: z.enum(['openai', 'claude']).default('claude'),
options: z
.object({
width: z.number().default(512),
height: z.number().default(768),
dummyMode: z.boolean().default(false),
})
.optional(),
});
export type ThemeExtractionRequest = z.infer<typeof themeExtractionRequestSchema>;
/**
* カラーテーマスキーマ(15色対応)
*/
export const colorThemeSchema = z.object({
// メインカラー
primary_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
secondary_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
accent_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
// セマンティックカラー
success_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
warning_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
error_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
info_semantic_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
// 背景色
primary_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
secondary_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
tertiary_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
overlay_background_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
// テキスト色
primary_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
secondary_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
disabled_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
inverse_text_color: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'カラーコードは#RRGGBBの形式で入力してください'),
});
export type ColorTheme = z.infer<typeof colorThemeSchema>;
/**
* デザイン特性スキーマ(フォントファミリー詳細化対応)
*/
export const designCharacteristicsSchema = z.object({
// フォントファミリー詳細化
heading_font_family: z.string(),
main_font_family: z.string(),
special_font_family: z.string(),
// デザイン特性
design_style: z.string(),
layout_type: z.string(),
});
export type DesignCharacteristics = z.infer<typeof designCharacteristicsSchema>;
/**
* ブランド印象スキーマ
*/
export const brandImpressionSchema = z.object({
brand_impression: z.array(z.string()),
industry_characteristics: z.string(),
});
export type BrandImpression = z.infer<typeof brandImpressionSchema>;
/**
* テーマ抽出結果スキーマ
*/
export const themeExtractionResultSchema = z.object({
colors: colorThemeSchema,
design: designCharacteristicsSchema,
brand: brandImpressionSchema,
analysis_notes: z.string(),
});
export type ThemeExtractionResult = z.infer<typeof themeExtractionResultSchema>;
/**
* テーマ抽出レスポンススキーマ
*/
export const themeExtractionResponseSchema = z.object({
success: z.boolean(),
data: themeExtractionResultSchema.optional(),
error: z.string().optional(),
metadata: z
.object({
url: z.string(),
provider: z.string(),
processingTime: z.number(),
screenshotTaken: z.boolean(),
timestamp: z.string(),
})
.optional(),
});
export type ThemeExtractionResponse = z.infer<typeof themeExtractionResponseSchema>;
/**
* AI応答パース用の中間スキーマ(15色+詳細フォント対応)
*/
export const rawThemeDataSchema = z.object({
colors: z.object({
// メインカラー
primary_color: z.string(),
secondary_color: z.string(),
accent_color: z.string(),
// セマンティックカラー
success_semantic_color: z.string(),
warning_semantic_color: z.string(),
error_semantic_color: z.string(),
info_semantic_color: z.string(),
// 背景色
primary_background_color: z.string(),
secondary_background_color: z.string(),
tertiary_background_color: z.string(),
overlay_background_color: z.string(),
// テキスト色
primary_text_color: z.string(),
secondary_text_color: z.string(),
disabled_text_color: z.string(),
inverse_text_color: z.string(),
}),
design: z.object({
// フォントファミリー詳細化
heading_font_family: z.string(),
main_font_family: z.string(),
special_font_family: z.string(),
// デザイン特性
design_style: z.string(),
layout_type: z.string(),
}),
brand: z.object({
brand_impression: z.array(z.string()),
industry_characteristics: z.string(),
}),
analysis_notes: z.string(),
});
export type RawThemeData = z.infer<typeof rawThemeDataSchema>;