import {
CourseContent,
CurationSuggestion,
CurationConfig,
Category,
Tag
} from '../types';
import {
MOCK_CATEGORIES,
MOCK_TAGS
} from '../data/mock-data';
import { AIService } from './ai.service';
export class ContentCurationService {
private categories: Category[];
private tags: Tag[];
private config: CurationConfig;
private aiService: AIService;
constructor(config?: Partial<CurationConfig>) {
this.categories = MOCK_CATEGORIES;
this.tags = MOCK_TAGS;
this.aiService = new AIService();
this.config = {
maxSuggestions: 5,
enableTitleSuggestions: true,
enableDescriptionSuggestions: true,
...config
};
}
async curateCourse(content: CourseContent): Promise<CurationSuggestion> {
if (!this.aiService.isEnabled()) {
throw new Error('OpenAI API key is required. Please set OPENAI_API_KEY environment variable.');
}
const [
suggestedCategory,
suggestedTags,
titleImprovement,
descriptionImprovement
] = await Promise.all([
this.suggestCategory(content),
this.suggestTags(content),
this.config.enableTitleSuggestions ? this.improveTitle(content.title, content.description) : Promise.resolve(undefined),
this.config.enableDescriptionSuggestions ? this.improveDescription(content.title, content.description) : Promise.resolve(undefined)
]);
return {
suggestedCategory,
suggestedTags,
titleImprovement,
descriptionImprovement
};
}
private async suggestCategory(content: CourseContent): Promise<CurationSuggestion['suggestedCategory']> {
const aiResult = await this.aiService.suggestCategoryWithAI(content, this.categories);
if (aiResult && aiResult.categoryId) {
const category = this.categories.find(c => c.id === aiResult.categoryId);
if (category) {
return {
id: category.id,
name: category.name,
confidence: aiResult.confidence,
reasoning: aiResult.reasoning
};
}
}
const defaultCategory = this.categories[0];
return {
id: defaultCategory.id,
name: defaultCategory.name,
confidence: 0.3,
reasoning: 'Categoria padrão - não foi possível analisar o conteúdo'
};
}
private async suggestTags(content: CourseContent): Promise<CurationSuggestion['suggestedTags']> {
const aiResult = await this.aiService.suggestTagsWithAI(content, this.tags);
if (aiResult && aiResult.length > 0) {
const validTags = aiResult
.map(aiTag => {
const tag = this.tags.find(t => t.id === aiTag.tagId);
return tag ? {
id: tag.id,
name: tag.name,
confidence: aiTag.confidence,
reasoning: aiTag.reasoning
} : null;
})
.filter(Boolean) as CurationSuggestion['suggestedTags'];
return validTags.slice(0, this.config.maxSuggestions);
}
return [];
}
private async improveTitle(title: string, description: string): Promise<CurationSuggestion['titleImprovement']> {
const aiResult = await this.aiService.improveTitleWithAI(title, description);
if (aiResult && aiResult.suggestion) {
return {
suggestion: aiResult.suggestion,
reasoning: aiResult.reasoning,
improvements: aiResult.improvements || []
};
}
return undefined;
}
private async improveDescription(title: string, description: string): Promise<CurationSuggestion['descriptionImprovement']> {
const aiResult = await this.aiService.improveDescriptionWithAI(title, description);
if (aiResult && aiResult.suggestion) {
return {
suggestion: aiResult.suggestion,
reasoning: aiResult.reasoning,
improvements: aiResult.improvements || []
};
}
return undefined;
}
getAIStatus(): { enabled: boolean; features: string[] } {
const enabled = this.aiService.isEnabled();
return {
enabled,
features: enabled ? [
'Categorização inteligente com GPT-4',
'Sugestão de tags contextual avançada',
'Melhoria de títulos com análise semântica',
'Melhoria de descrições personalizada',
'Análise de similaridade precisa'
] : []
};
}
}