-- astock-kg 因子插槽接口：只读视图（供 akg-factor-bridge 消费）
-- 应用：docker compose exec -T akg-factor-bridge python run.py apply-views
--
-- 用 DROP + CREATE 而非 CREATE OR REPLACE：后者不允许改变已有列的名字与顺序
-- （只能在末尾追加），而本次调整了列。已确认这四个视图在 astock-kg 内无任何
-- 消费方（grep v_factor_ 零命中），DROP 安全。
-- 顺序要求：ALTER 必须在引用新列的视图之前。

ALTER TABLE transmission_candidates ADD COLUMN IF NOT EXISTS mkt_trade_date DATE;
CREATE INDEX IF NOT EXISTS idx_tc_target ON transmission_candidates (target, scan_date);


-- 覆盖池 universe = 全部 industry_pools 成员并集。
-- 注意它是当前态：池只存最新快照、每周一 refresh_pools 自动长大。
DROP VIEW IF EXISTS v_factor_universe;
CREATE VIEW v_factor_universe AS
SELECT DISTINCT m->>'ts_code' AS ts_code
FROM industry_pools p
CROSS JOIN LATERAL jsonb_array_elements(COALESCE(p.members, '[]'::jsonb)) AS m
WHERE m->>'ts_code' IS NOT NULL AND m->>'ts_code' <> '';


-- 一致预期（供 upside）：桥按 trade_date 做 as-of backward。
DROP VIEW IF EXISTS v_factor_consensus;
CREATE VIEW v_factor_consensus AS
SELECT ts_code, asof_date, target_mid_avg, eps_med, np_med, n_orgs, n_reports_90d
FROM consensus_daily
WHERE target_mid_avg IS NOT NULL;


-- 利好利空事件（供 event）。
-- source_type 供桥做年报污染防护：年报同样带 company_ts_code 锚，而一份年报能抽
-- 十几条 EVENT 且含历史诉讼/处罚，会在披露日形成负值尖峰。
-- doc_id 供单文档封顶。取值：annual_report/research_report/announcement/news/interactive_qa
DROP VIEW IF EXISTS v_factor_events;
CREATE VIEW v_factor_events AS
SELECT d.meta->>'company_ts_code'   AS ts_code,
       c.disclosure_date,
       c.qualifiers->>'event_type'  AS event_type,
       c.qualifiers->>'direction'   AS direction,
       c.qualifiers->>'scope'       AS scope,
       c.confidence,
       c.tier,
       c.dedup_key,
       c.doc_id,
       d.source_type
FROM claims c
JOIN documents d ON d.doc_id = c.doc_id
WHERE c.predicate = 'EVENT'
  AND d.meta->>'company_ts_code' IS NOT NULL;


-- 板块传导（供 transmission）：quiet 未动成员摊平成每股一行。
-- n_sources = 指向该环节的 distinct 源数（新）；n_paths = 原路径条数（保留原义）。
-- 二者的比值就是路径重复计数的倍数：cascade 的变长边 *1..N 每种长度各返回一条，
-- transmission_targets 的 updown/supply/drives 三桶之间也不去重。
-- members_total / n_quiet_stored / mkt_trade_date 供桥自检上游截断与快照新鲜度。
DROP VIEW IF EXISTS v_factor_transmission;
CREATE VIEW v_factor_transmission AS
SELECT t.scan_date,
       q->>'ts_code'                                       AS ts_code,
       jsonb_array_length(COALESCE(t.paths, '[]'::jsonb))  AS n_paths,
       t.moved_ratio,
       (SELECT count(DISTINCT p->>'source')
          FROM jsonb_array_elements(COALESCE(t.paths, '[]'::jsonb)) p) AS n_sources,
       t.rank,
       t.target,
       t.target_type,
       t.members_total,
       t.moved,
       jsonb_array_length(COALESCE(t.quiet, '[]'::jsonb))  AS n_quiet_stored,
       t.mkt_trade_date
FROM transmission_candidates t
CROSS JOIN LATERAL jsonb_array_elements(COALESCE(t.quiet, '[]'::jsonb)) AS q
WHERE q->>'ts_code' IS NOT NULL AND q->>'ts_code' <> '';

-- ------------------------------------------------------- 第五/六插槽（G2·三批-4）
-- 环节投影视图：底表由基座任务 akg.project_segments 每晨 06:10 删后插刷新。
-- 成员可审计到 IN_SEGMENT 边（含链名修饰 chain）；链序结构 = SEGMENT_UPSTREAM_OF，
-- 环节级逻辑边 = DRIVES。赛道门槛 C 的 kg_segments 映射路径读这里。
CREATE OR REPLACE VIEW v_factor_segment_members AS
SELECT segment_name, ts_code, member_name, member_label, chain, projected_at
FROM segment_members_projection;

CREATE OR REPLACE VIEW v_factor_segment_edges AS
SELECT src_segment, dst_segment, rel_type, direction, mechanism, chain, projected_at
FROM segment_edges_projection;
