fix monitoring manual mark attribution
Frontend CI / Frontend (push) Successful in 2m56s
Backend CI / Backend (push) Successful in 14m47s

This commit is contained in:
2026-06-25 09:31:18 +08:00
parent bdfe79c921
commit cbbec8da85
10 changed files with 436 additions and 66 deletions
@@ -0,0 +1,2 @@
DROP INDEX IF EXISTS idx_citation_facts_manual_mark_refresh;
DROP INDEX IF EXISTS idx_citation_facts_manual_mark_sync_candidates;
@@ -0,0 +1,21 @@
CREATE INDEX IF NOT EXISTS idx_citation_facts_manual_mark_sync_candidates
ON monitoring_citation_facts (
tenant_id,
business_date,
registrable_domain,
site_key,
host
)
WHERE content_source_type IS NULL
AND content_source_id IS NULL;
CREATE INDEX IF NOT EXISTS idx_citation_facts_manual_mark_refresh
ON monitoring_citation_facts (
tenant_id,
content_source_type,
content_source_id,
brand_id,
business_date
)
WHERE content_source_type = 'manual_mark'
AND content_source_id IS NOT NULL;
@@ -0,0 +1,53 @@
CREATE TEMP TABLE tmp_manual_mark_backfill_affected ON COMMIT DROP AS
WITH cleared_facts AS (
UPDATE monitoring_citation_facts cf
SET content_source_type = NULL,
content_source_id = NULL
FROM monitoring_user_marked_articles marked
WHERE marked.tenant_id = cf.tenant_id
AND marked.id = cf.content_source_id
AND cf.content_source_type = 'manual_mark'
AND btrim(cf.normalized_url, '/') = btrim(marked.normalized_url, '/')
RETURNING cf.tenant_id, cf.brand_id, cf.business_date
)
SELECT DISTINCT tenant_id, brand_id, business_date
FROM cleared_facts;
WITH citation_counts AS (
SELECT
affected.tenant_id,
affected.brand_id,
affected.business_date,
runs.collector_type,
COUNT(DISTINCT cf.run_id)::int AS cited_answer_count
FROM tmp_manual_mark_backfill_affected affected
JOIN monitoring_citation_facts cf
ON cf.tenant_id = affected.tenant_id
AND cf.brand_id = affected.brand_id
AND cf.business_date = affected.business_date
AND cf.content_source_type IS NOT NULL
AND cf.content_source_id IS NOT NULL
JOIN question_monitor_runs runs
ON runs.tenant_id = cf.tenant_id
AND runs.id = cf.run_id
AND runs.business_date = cf.business_date
AND runs.status = 'succeeded'
GROUP BY affected.tenant_id, affected.brand_id, affected.business_date, runs.collector_type
)
UPDATE monitoring_brand_daily daily
SET cited_answer_count = COALESCE(counts.cited_answer_count, 0),
citation_rate = CASE
WHEN daily.actual_sample_count > 0
THEN COALESCE(counts.cited_answer_count, 0)::numeric / daily.actual_sample_count::numeric
ELSE NULL
END,
updated_at = NOW()
FROM tmp_manual_mark_backfill_affected affected
LEFT JOIN citation_counts counts
ON counts.tenant_id = affected.tenant_id
AND counts.brand_id = affected.brand_id
AND counts.business_date = affected.business_date
WHERE daily.tenant_id = affected.tenant_id
AND daily.brand_id = affected.brand_id
AND daily.business_date = affected.business_date
AND (counts.collector_type IS NULL OR daily.collector_type = counts.collector_type);
@@ -0,0 +1,60 @@
CREATE TEMP TABLE tmp_manual_mark_backfill_affected ON COMMIT DROP AS
WITH matched_facts AS (
SELECT DISTINCT ON (cf.id)
cf.id AS citation_fact_id,
marked.id AS marked_article_id
FROM monitoring_citation_facts cf
JOIN monitoring_user_marked_articles marked
ON marked.tenant_id = cf.tenant_id
AND marked.expires_at > NOW()
WHERE cf.content_source_type IS NULL
AND cf.content_source_id IS NULL
AND cf.business_date >= (CURRENT_DATE - INTERVAL '6 months')::date
AND btrim(cf.normalized_url, '/') = btrim(marked.normalized_url, '/')
ORDER BY cf.id, marked.updated_at DESC, marked.id DESC
),
updated_facts AS (
UPDATE monitoring_citation_facts cf
SET content_source_type = 'manual_mark',
content_source_id = matched.marked_article_id
FROM matched_facts matched
WHERE cf.id = matched.citation_fact_id
RETURNING cf.tenant_id, cf.brand_id, cf.business_date
)
SELECT DISTINCT tenant_id, brand_id, business_date
FROM updated_facts;
WITH citation_counts AS (
SELECT
affected.tenant_id,
affected.brand_id,
affected.business_date,
runs.collector_type,
COUNT(DISTINCT cf.run_id)::int AS cited_answer_count
FROM tmp_manual_mark_backfill_affected affected
JOIN monitoring_citation_facts cf
ON cf.tenant_id = affected.tenant_id
AND cf.brand_id = affected.brand_id
AND cf.business_date = affected.business_date
AND cf.content_source_type IS NOT NULL
AND cf.content_source_id IS NOT NULL
JOIN question_monitor_runs runs
ON runs.tenant_id = cf.tenant_id
AND runs.id = cf.run_id
AND runs.business_date = cf.business_date
AND runs.status = 'succeeded'
GROUP BY affected.tenant_id, affected.brand_id, affected.business_date, runs.collector_type
)
UPDATE monitoring_brand_daily daily
SET cited_answer_count = counts.cited_answer_count,
citation_rate = CASE
WHEN daily.actual_sample_count > 0
THEN counts.cited_answer_count::numeric / daily.actual_sample_count::numeric
ELSE NULL
END,
updated_at = NOW()
FROM citation_counts counts
WHERE daily.tenant_id = counts.tenant_id
AND daily.brand_id = counts.brand_id
AND daily.business_date = counts.business_date
AND daily.collector_type = counts.collector_type;