import { parseApiResponse } from '@/api-client/utils/parseApiResponse'; import { rpcClient } from '@/api-client/utils/rpc-client'; import type { SwotData, SwotDataWithoutSummary } from '@/schema/pox'; import { generateContentsHtmlResponseSchema, generateFvHtmlResponseSchema, type ContentSection, type FvData, type GenerateContentsHtmlResponse, type GenerateFvHtmlResponse, } from '@/schema/proposal'; import type { ThemeExtractionResult } from '@/schema/theme-extraction'; /** * FV提案のHTML生成 */ export async function generateFvHtml(params: { tabName: string; fvData: FvData; provider?: 'openai' | 'gemini' | 'claude'; referenceUrl?: string; screenshot?: string; dummyMode?: boolean; swotData?: SwotData | SwotDataWithoutSummary; userEmail?: string; sourcePage?: string; forceFallbackMode?: boolean; themeData?: ThemeExtractionResult | null; }): Promise { // テーマデータがある場合はログ出力のみ(将来のAPI対応用) if (params.themeData) { console.log('[FV HTML] テーマデータが適用されます:', params.themeData); } const response = await rpcClient.proposal['html-preview']['generate-fv-html'].$post({ json: { tabName: params.tabName, fvData: params.fvData, provider: params.provider, referenceUrl: params.referenceUrl, screenshotUrl: params.screenshot, // パラメータ名をscreenshotUrlに変換 dummyMode: params.dummyMode, swotData: params.swotData, userEmail: params.userEmail, sourcePage: params.sourcePage, forceFallbackMode: params.forceFallbackMode, themeData: params.themeData ?? undefined, // nullをundefinedに変換 }, }); return parseApiResponse(response, generateFvHtmlResponseSchema); } /** * コンテンツ提案のHTML生成 */ export async function generateContentsHtml(params: { tabName: string; cnData: ContentSection[]; provider?: 'openai' | 'gemini' | 'claude'; referenceUrl?: string; screenshot?: string; dummyMode?: boolean; userEmail?: string; themeData?: ThemeExtractionResult | null; }): Promise { // テーマデータがある場合はログ出力のみ(将来のAPI対応用) if (params.themeData) { console.log('[CONTENTS HTML] テーマデータが適用されます:', params.themeData); } const response = await rpcClient.proposal['html-preview']['generate-contents-html'].$post({ json: { tabName: params.tabName, cnData: params.cnData, provider: params.provider, referenceUrl: params.referenceUrl, screenshotUrl: params.screenshot, // パラメータ名をscreenshotUrlに変換 dummyMode: params.dummyMode, userEmail: params.userEmail, themeData: params.themeData ?? undefined, // nullをundefinedに変換 }, }); return parseApiResponse(response, generateContentsHtmlResponseSchema); } /** * 画像生成を開始 */ export async function startImageGeneration( html: string, tabName: string, cnData: ContentSection[], provider: 'openai' | 'claude' = 'claude', ): Promise<{ batchId: string; estimatedCompletionTime: string; message: string; status: string; }> { const response = await fetch('/api/rpc/proposal/start-contents-image-generation', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ html, tabName, cnData, provider, }), }); if (!response.ok) { throw new Error(`画像生成開始に失敗しました: ${response.statusText}`); } return response.json(); } /** * 画像生成状況を確認 */ export async function getImageGenerationStatus(batchId: string): Promise<{ batchId: string; status: 'pending' | 'processing' | 'completed' | 'failed'; jobs: Array<{ jobId: string; imageId: string; status: 'pending' | 'generating' | 'completed' | 'failed'; generatedImageUrl?: string; errorMessage?: string; }>; createdAt: string; completedAt?: string; } | null> { const response = await fetch(`/api/rpc/proposal/image-generation-status/${batchId}`); if (!response.ok) { if (response.status === 404) { // バッチIDが存在しない場合は null を返す return null; } throw new Error(`ステータス確認に失敗しました: ${response.statusText}`); } return response.json(); }