GitHub Action
Sync from GitHub
ef78361
Raw
History Blame Contribute Delete
5.14 kB
"""Trigger analysis section β€” date picker, run, preview, save.
Separated from overview.py so that CRUD operations work even when
trigger_rules module is unavailable (e.g., standalone HuggingFace Space).
"""
from datetime import date, timedelta
import streamlit as st
from core.supabase_client import (
get_campaign_date_range,
save_action_items_batch,
)
from .triggers import TRIGGERS_AVAILABLE
from .utils import priority_level, CATEGORY_CONFIG
def render_analysis_section(campaign_id: int, base_ctx: dict):
"""Render trigger analysis: date picker, run button, preview, save."""
with st.expander("πŸ” 트리거 뢄석 μ‹€ν–‰", expanded=True):
if not TRIGGERS_AVAILABLE:
st.info(
"트리거 뢄석 κΈ°λŠ₯을 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. "
"전체 ν”„λ‘œμ νŠΈ ν™˜κ²½μ—μ„œλ§Œ μ§€μ›λ©λ‹ˆλ‹€."
)
return
# Date range
date_range = get_campaign_date_range(campaign_id)
if not date_range:
st.info("캠페인 데이터가 아직 λ™κΈ°ν™”λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.")
return
_, last_date_str = date_range
last_date = date.fromisoformat(last_date_str)
default_start = last_date - timedelta(days=6)
date_cols = st.columns(2)
with date_cols[0]:
start_date = st.date_input(
"μ‹œμž‘μΌ",
value=default_start,
key="ai_trigger_start",
)
with date_cols[1]:
end_date = st.date_input(
"μ’…λ£ŒμΌ",
value=last_date,
key="ai_trigger_end",
)
if st.button("πŸ” 뢄석 μ‹€ν–‰", key="ai_run_triggers", type="primary", use_container_width=True):
with st.spinner("14개 트리거 κ·œμΉ™μ„ 평가 쀑..."):
try:
from .triggers import evaluate_triggers
results = evaluate_triggers(
campaign_id,
start_date.isoformat(),
end_date.isoformat(),
)
st.session_state["ai_trigger_results"] = results
except Exception as e:
st.error(f"뢄석 였λ₯˜: {e}")
return
# Show results if available
results = st.session_state.get("ai_trigger_results")
if results is None:
return
if not results:
st.success("λͺ¨λ“  μ§€ν‘œκ°€ 정상 λ²”μœ„μž…λ‹ˆλ‹€. νƒμ§€λœ μ‹ ν˜Έκ°€ μ—†μŠ΅λ‹ˆλ‹€.")
return
st.markdown(f"**{len(results)}개 μ‹ ν˜Έ 탐지됨**")
# Preview cards
for item in results:
p_label, p_color, p_bg = priority_level(item["priority"])
cat_cfg = CATEGORY_CONFIG.get(item["category"], {"color": "#666", "icon": "πŸ“Œ"})
st.markdown(f"""
<div style="background:#FAFAFA;border:1px solid #E5E7EB;border-radius:8px;
padding:12px;margin-bottom:8px;border-left:3px solid {p_color}">
<div style="display:flex;gap:8px;align-items:center;margin-bottom:6px">
<span style="background:{p_bg};color:{p_color};padding:1px 8px;
border-radius:10px;font-size:11px;font-weight:600">{p_label}</span>
<span style="font-size:11px;color:{cat_cfg['color']}">{cat_cfg['icon']} {item['category']}</span>
</div>
<div style="font-size:14px;font-weight:600;color:#1F2937;margin-bottom:4px">{item['label']}</div>
<div style="font-size:12px;color:#6B7280">{item.get('evidence', '')}</div>
</div>
""", unsafe_allow_html=True)
# Save button
if st.button("πŸ’Ύ μ•‘μ…˜μ•„μ΄ν…œμœΌλ‘œ μ €μž₯", key="ai_save_triggers", use_container_width=True):
_save_trigger_results(campaign_id, results, base_ctx)
def _save_trigger_results(campaign_id: int, results: list[dict], base_ctx: dict):
"""Save trigger analysis results as action items."""
try:
from core.supabase_client import get_supabase_client
user_client = get_supabase_client()
key_result = (
user_client.table("api_keys")
.select("user_id")
.limit(1)
.execute()
)
user_id = str(key_result.data[0]["user_id"]) if key_result.data else "unknown"
result = save_action_items_batch(
campaign_id=campaign_id,
user_id=user_id,
items=results,
)
created = result.get("created", 0)
skipped = result.get("skipped", 0)
if result.get("error"):
st.error(f"μ €μž₯ 였λ₯˜: {result['error']}")
elif created > 0:
st.success(f"βœ… {created}개 μ €μž₯ μ™„λ£Œ (쀑볡 {skipped}개 μŠ€ν‚΅)")
st.session_state.pop("ai_trigger_results", None)
st.rerun()
else:
st.info(f"λͺ¨λ“  ν•­λͺ©μ΄ 이미 μ‘΄μž¬ν•©λ‹ˆλ‹€ ({skipped}개 μŠ€ν‚΅)")
except Exception as e:
st.error(f"μ €μž₯ μ‹€νŒ¨: {e}")