feat: Introduce AI Brand Monitoring System V5 technical design document

- Added comprehensive technical design document for AI Brand Monitoring System V5, outlining system architecture, data models, sampling strategies, and monitoring protocols.
- Key changes include a shift to a sampling-based trend monitoring approach, updated data collection and storage strategies, and new metrics for performance evaluation.
- Implemented migration scripts to support the flattening of brand questions and versioning of question texts, ensuring historical data integrity and version control.
This commit is contained in:
2026-04-09 14:43:20 +08:00
parent 41f8e0621e
commit 36451a613d
18 changed files with 2709 additions and 234 deletions
@@ -46,36 +46,20 @@ UPDATE brand_keywords SET deleted_at = NOW(), updated_at = NOW()
WHERE brand_id = sqlc.arg(brand_id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
-- name: ListQuestions :many
SELECT q.id, q.tenant_id, q.brand_id, q.keyword_id, q.current_version_id, q.status, q.created_at,
v.question_text, v.version_no
SELECT q.id, q.tenant_id, q.brand_id, q.keyword_id, q.question_text, q.status, q.created_at
FROM brand_questions q
LEFT JOIN brand_question_versions v ON v.id = q.current_version_id
WHERE q.brand_id = sqlc.arg(brand_id) AND q.tenant_id = sqlc.arg(tenant_id) AND q.deleted_at IS NULL
AND (sqlc.narg(keyword_id)::bigint IS NULL OR q.keyword_id = sqlc.narg(keyword_id))
ORDER BY q.created_at DESC;
-- name: CreateQuestion :one
INSERT INTO brand_questions (tenant_id, brand_id, keyword_id, status)
VALUES (sqlc.arg(tenant_id), sqlc.arg(brand_id), sqlc.arg(keyword_id), 'active')
INSERT INTO brand_questions (tenant_id, brand_id, keyword_id, question_text, status)
VALUES (sqlc.arg(tenant_id), sqlc.arg(brand_id), sqlc.arg(keyword_id), sqlc.arg(question_text), 'active')
RETURNING id;
-- name: CreateQuestionVersion :one
INSERT INTO brand_question_versions (question_id, question_text, question_hash, version_no, is_active)
VALUES (sqlc.arg(question_id), sqlc.arg(question_text), sqlc.arg(question_hash), sqlc.arg(version_no), true)
RETURNING id;
-- name: UpdateQuestionCurrentVersion :exec
UPDATE brand_questions SET current_version_id = sqlc.arg(version_id), updated_at = NOW()
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
-- name: DeactivateQuestionVersion :exec
UPDATE brand_question_versions SET is_active = false
WHERE question_id = sqlc.arg(question_id) AND is_active = true;
-- name: GetLatestQuestionVersionNo :one
SELECT COALESCE(MAX(version_no), 0)::INT AS max_version
FROM brand_question_versions
WHERE question_id = sqlc.arg(question_id);
-- name: UpdateQuestion :exec
UPDATE brand_questions SET question_text = sqlc.arg(question_text), updated_at = NOW()
WHERE id = sqlc.arg(id) AND brand_id = sqlc.arg(brand_id) AND tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
-- name: SoftDeleteQuestion :exec
UPDATE brand_questions SET deleted_at = NOW(), updated_at = NOW()