feat(admin-brand): add question expansion service and related functionality
- Implemented QuestionExpansionService for generating and materializing questions based on combinations and AI distillation. - Added question metadata classification logic to infer intent and layer of questions. - Created API handlers for question expansion operations including combination preview, AI distillation, metadata classification, and materialization. - Introduced database migrations to support new question-related fields and constraints in brand_questions and brand_keywords tables. - Added caching mechanism for AI distillation results to improve performance. - Defined JSON schemas for question distillation responses to ensure data integrity.
This commit is contained in:
@@ -1214,6 +1214,7 @@ export interface Brand {
|
||||
status: string
|
||||
keyword_count: number
|
||||
question_count: number
|
||||
competitor_count?: number
|
||||
created_at: string
|
||||
updated_at?: string
|
||||
}
|
||||
@@ -1257,7 +1258,75 @@ export interface BrandLibrarySummary {
|
||||
max_keywords: number
|
||||
used_keywords: number
|
||||
remaining_keywords: number
|
||||
max_questions: number
|
||||
used_questions: number
|
||||
remaining_questions: number
|
||||
max_questions_per_keyword: number
|
||||
max_questions_per_brand: number
|
||||
}
|
||||
|
||||
export type QuestionSource = 'manual' | 'combination' | 'ai_distill'
|
||||
export type QuestionIntent = 'informational' | 'evaluative' | 'decisional'
|
||||
export type QuestionLayer = 'L1' | 'L2' | 'L3' | 'L4' | 'L5'
|
||||
|
||||
export interface QuestionCombinationRequest {
|
||||
region?: string[]
|
||||
prefix?: string[]
|
||||
core: string[]
|
||||
industry: string[]
|
||||
suffix?: string[]
|
||||
max_items?: number
|
||||
}
|
||||
|
||||
export interface QuestionDistillRequest {
|
||||
seed_topic: string
|
||||
}
|
||||
|
||||
export interface QuestionCandidate {
|
||||
text: string
|
||||
layer: QuestionLayer
|
||||
intent: QuestionIntent
|
||||
source: QuestionSource
|
||||
missing_suffix?: boolean
|
||||
too_short?: boolean
|
||||
duplicate?: boolean
|
||||
suggest_skip?: boolean
|
||||
}
|
||||
|
||||
export interface QuestionCandidateResult {
|
||||
candidates: QuestionCandidate[]
|
||||
ai_points_charged?: number
|
||||
cache_hit?: boolean
|
||||
truncated?: boolean
|
||||
}
|
||||
|
||||
export interface ClassifiedQuestion {
|
||||
text: string
|
||||
layer: QuestionLayer
|
||||
intent: QuestionIntent
|
||||
}
|
||||
|
||||
export interface MaterializeQuestion {
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface MaterializeQuestionsRequest {
|
||||
source: QuestionSource
|
||||
questions: MaterializeQuestion[]
|
||||
}
|
||||
|
||||
export interface SkipReason {
|
||||
text: string
|
||||
reason: string
|
||||
}
|
||||
|
||||
export interface MaterializeQuestionsResult {
|
||||
created_questions: number
|
||||
skipped_questions: SkipReason[]
|
||||
}
|
||||
|
||||
export interface ClassifyQuestionsRequest {
|
||||
texts: string[]
|
||||
}
|
||||
|
||||
export interface CompetitorRequest {
|
||||
|
||||
Reference in New Issue
Block a user