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:
@@ -0,0 +1,19 @@
|
||||
DROP INDEX IF EXISTS uk_brand_question_text_active;
|
||||
DROP INDEX IF EXISTS idx_brand_questions_intent;
|
||||
|
||||
ALTER TABLE brand_questions
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_questions_layer,
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_questions_intent,
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_questions_source,
|
||||
DROP COLUMN IF EXISTS source,
|
||||
DROP COLUMN IF EXISTS intent,
|
||||
DROP COLUMN IF EXISTS layer;
|
||||
|
||||
DROP INDEX IF EXISTS idx_brand_keywords_internal_source;
|
||||
|
||||
ALTER TABLE brand_keywords
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_keywords_layer,
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_keywords_source,
|
||||
DROP COLUMN IF EXISTS source,
|
||||
DROP COLUMN IF EXISTS seed_word,
|
||||
DROP COLUMN IF EXISTS layer;
|
||||
@@ -0,0 +1,44 @@
|
||||
ALTER TABLE brand_keywords
|
||||
ADD COLUMN IF NOT EXISTS layer VARCHAR(8) NOT NULL DEFAULT 'L2',
|
||||
ADD COLUMN IF NOT EXISTS seed_word VARCHAR(200),
|
||||
ADD COLUMN IF NOT EXISTS source VARCHAR(32) NOT NULL DEFAULT 'manual';
|
||||
|
||||
ALTER TABLE brand_keywords
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_keywords_layer,
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_keywords_source;
|
||||
|
||||
ALTER TABLE brand_keywords
|
||||
ADD CONSTRAINT ck_brand_keywords_layer
|
||||
CHECK (layer IN ('L1','L2','L3','L4','L5')),
|
||||
ADD CONSTRAINT ck_brand_keywords_source
|
||||
CHECK (source IN ('manual','combination','ai_distill','auto'));
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_brand_keywords_internal_source
|
||||
ON brand_keywords (tenant_id, brand_id, source)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE brand_questions
|
||||
ADD COLUMN IF NOT EXISTS layer VARCHAR(8) NOT NULL DEFAULT 'L2',
|
||||
ADD COLUMN IF NOT EXISTS intent VARCHAR(16) NOT NULL DEFAULT 'informational',
|
||||
ADD COLUMN IF NOT EXISTS source VARCHAR(32) NOT NULL DEFAULT 'manual';
|
||||
|
||||
ALTER TABLE brand_questions
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_questions_layer,
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_questions_intent,
|
||||
DROP CONSTRAINT IF EXISTS ck_brand_questions_source;
|
||||
|
||||
ALTER TABLE brand_questions
|
||||
ADD CONSTRAINT ck_brand_questions_layer
|
||||
CHECK (layer IN ('L1','L2','L3','L4','L5')),
|
||||
ADD CONSTRAINT ck_brand_questions_intent
|
||||
CHECK (intent IN ('informational','evaluative','decisional')),
|
||||
ADD CONSTRAINT ck_brand_questions_source
|
||||
CHECK (source IN ('manual','combination','ai_distill'));
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_brand_questions_intent
|
||||
ON brand_questions (tenant_id, brand_id, intent)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_brand_question_text_active
|
||||
ON brand_questions (tenant_id, brand_id, lower(btrim(question_text)))
|
||||
WHERE deleted_at IS NULL;
|
||||
Reference in New Issue
Block a user