report 패치 함수 추가. 데이터 직결용
parent
1f45b3e53d
commit
09bb7a71ee
|
|
@ -148,7 +148,7 @@ async def is_done(table: str, row_id: int | None) -> bool:
|
||||||
return r["status"] == "done"
|
return r["status"] == "done"
|
||||||
|
|
||||||
|
|
||||||
async def _fetch_raw(table: str, row_id: int | None) -> dict | None:
|
async def fetch_raw(table: str, row_id: int | None) -> dict | None:
|
||||||
if row_id is None:
|
if row_id is None:
|
||||||
return None
|
return None
|
||||||
row = await fetchone(f"SELECT raw_data FROM {table} WHERE id = %s", (row_id,))
|
row = await fetchone(f"SELECT raw_data FROM {table} WHERE id = %s", (row_id,))
|
||||||
|
|
@ -164,11 +164,11 @@ async def get_analysis_raw_data(analysis_run_id: str) -> dict:
|
||||||
(analysis_run_id,),
|
(analysis_run_id,),
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
"instagram": await _fetch_raw("instagram_data", run["instagram_data_id"]),
|
"instagram": await fetch_raw("instagram_data", run["instagram_data_id"]),
|
||||||
"facebook": await _fetch_raw("facebook_data", run["facebook_data_id"]),
|
"facebook": await fetch_raw("facebook_data", run["facebook_data_id"]),
|
||||||
"naver_blog": await _fetch_raw("naver_blog_data", run["naver_blog_data_id"]),
|
"naver_blog": await fetch_raw("naver_blog_data", run["naver_blog_data_id"]),
|
||||||
"youtube": await _fetch_raw("youtube_data", run["youtube_data_id"]),
|
"youtube": await fetch_raw("youtube_data", run["youtube_data_id"]),
|
||||||
"gangnam_unni": await _fetch_raw("gangnam_unni_data", run["gangnam_unni_data_id"]),
|
"gangnam_unni": await fetch_raw("gangnam_unni_data", run["gangnam_unni_data_id"]),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from common.db import fetchone, execute, get_analysis_raw_data, save_analysis_report, get_market_analysis
|
from common.db import fetchone, execute, fetch_raw, get_analysis_raw_data, save_analysis_report, get_market_analysis
|
||||||
from integrations.llm.llm_service import LLMService
|
from integrations.llm.llm_service import LLMService
|
||||||
from integrations.llm.prompt import report_prompt, plan_prompt
|
from integrations.llm.prompt import report_prompt, plan_prompt
|
||||||
from integrations.llm.schemas.report import ReportOutput
|
from integrations.llm.schemas.report import ReportOutput
|
||||||
|
|
@ -47,7 +47,6 @@ async def generate_report(analysis_run_id: str) -> ReportOutput:
|
||||||
|
|
||||||
return await LLMService(provider="perplexity").generate(report_prompt, input_data)
|
return await LLMService(provider="perplexity").generate(report_prompt, input_data)
|
||||||
|
|
||||||
|
|
||||||
async def generate_plan(analysis_run_id: str) -> PlanOutput:
|
async def generate_plan(analysis_run_id: str) -> PlanOutput:
|
||||||
run = await fetchone(
|
run = await fetchone(
|
||||||
"SELECT hospital_id, report_data FROM analysis_runs WHERE analysis_run_id = %s",
|
"SELECT hospital_id, report_data FROM analysis_runs WHERE analysis_run_id = %s",
|
||||||
|
|
@ -84,9 +83,84 @@ async def generate_plan(analysis_run_id: str) -> PlanOutput:
|
||||||
return await LLMService(provider="perplexity").generate(plan_prompt, input_data)
|
return await LLMService(provider="perplexity").generate(plan_prompt, input_data)
|
||||||
|
|
||||||
|
|
||||||
|
async def _build_overrides(analysis_run_id: str) -> dict:
|
||||||
|
run = await fetchone(
|
||||||
|
"SELECT hospital_id, instagram_data_id, facebook_data_id,"
|
||||||
|
" naver_blog_data_id, youtube_data_id, gangnam_unni_data_id"
|
||||||
|
" FROM analysis_runs WHERE analysis_run_id = %s",
|
||||||
|
(analysis_run_id,),
|
||||||
|
)
|
||||||
|
if not run:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
hospital_row = await fetchone(
|
||||||
|
"SELECT raw_data FROM hospital_baseinfo WHERE hospital_id = %s",
|
||||||
|
(run["hospital_id"],),
|
||||||
|
)
|
||||||
|
hospital = json.loads(hospital_row["raw_data"]) if hospital_row and isinstance(hospital_row.get("raw_data"), str) else (hospital_row or {}).get("raw_data") or {}
|
||||||
|
instagram = await fetch_raw("instagram_data", run["instagram_data_id"]) or {}
|
||||||
|
facebook = await fetch_raw("facebook_data", run["facebook_data_id"]) or {}
|
||||||
|
naver_blog = await fetch_raw("naver_blog_data", run["naver_blog_data_id"]) or {}
|
||||||
|
youtube = await fetch_raw("youtube_data", run["youtube_data_id"]) or {}
|
||||||
|
gangnam_unni = await fetch_raw("gangnam_unni_data", run["gangnam_unni_data_id"]) or {}
|
||||||
|
|
||||||
|
snapshot: dict = {}
|
||||||
|
|
||||||
|
# ── gangnam_unni ──────────────────────────────────────────────────────────
|
||||||
|
doctors = gangnam_unni.get("doctors", [])
|
||||||
|
lead = max(doctors, key=lambda d: d.get("reviews", 0)) if doctors else None
|
||||||
|
if gangnam_unni.get("name"): snapshot["name"] = gangnam_unni["name"]
|
||||||
|
if gangnam_unni.get("rating"): snapshot["overall_rating"] = gangnam_unni["rating"]
|
||||||
|
if gangnam_unni.get("totalReviews"): snapshot["total_reviews"] = gangnam_unni["totalReviews"]
|
||||||
|
if gangnam_unni.get("address"): snapshot["location"] = gangnam_unni["address"]
|
||||||
|
if gangnam_unni.get("badges"): snapshot["certifications"] = gangnam_unni["badges"]
|
||||||
|
if doctors: snapshot["staff_count"] = len(doctors)
|
||||||
|
if lead:
|
||||||
|
snapshot["lead_doctor"] = {
|
||||||
|
"name": lead.get("name"),
|
||||||
|
"credentials": lead.get("specialty"),
|
||||||
|
"rating": lead.get("rating"),
|
||||||
|
"review_count": lead.get("reviews"),
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── instagram ─────────────────────────────────────────────────────────────
|
||||||
|
ig_patch: dict = {}
|
||||||
|
if instagram.get("username"): ig_patch["handle"] = instagram["username"]
|
||||||
|
if instagram.get("posts"): ig_patch["posts"] = instagram["posts"]
|
||||||
|
if instagram.get("followers"): ig_patch["followers"] = instagram["followers"]
|
||||||
|
if instagram.get("following"): ig_patch["following"] = instagram["following"]
|
||||||
|
if instagram.get("bio"): ig_patch["bio"] = instagram["bio"]
|
||||||
|
if instagram.get("username"): ig_patch["profile_link"] = f"https://www.instagram.com/{instagram['username']}/"
|
||||||
|
|
||||||
|
overrides: dict = {}
|
||||||
|
if snapshot:
|
||||||
|
overrides["clinic_snapshot"] = snapshot
|
||||||
|
if ig_patch:
|
||||||
|
overrides["instagram_audit"] = {"accounts": [ig_patch]}
|
||||||
|
return overrides
|
||||||
|
|
||||||
|
|
||||||
|
def _deep_merge(base: dict, overrides: dict) -> dict:
|
||||||
|
for k, v in overrides.items():
|
||||||
|
if isinstance(v, dict) and isinstance(base.get(k), dict):
|
||||||
|
_deep_merge(base[k], v)
|
||||||
|
elif isinstance(v, list) and isinstance(base.get(k), list):
|
||||||
|
for i, item in enumerate(v):
|
||||||
|
if i < len(base[k]) and isinstance(item, dict) and isinstance(base[k][i], dict):
|
||||||
|
_deep_merge(base[k][i], item)
|
||||||
|
else:
|
||||||
|
base[k] = v
|
||||||
|
return base
|
||||||
|
|
||||||
|
def _patch_report(result: ReportOutput, overrides: dict) -> ReportOutput:
|
||||||
|
merged = _deep_merge(result.model_dump(), overrides)
|
||||||
|
return ReportOutput(**merged)
|
||||||
|
|
||||||
|
|
||||||
async def run_report_task(analysis_run_id: str) -> None:
|
async def run_report_task(analysis_run_id: str) -> None:
|
||||||
logger.info("[report] start run=%s", analysis_run_id)
|
logger.info("[report] start run=%s", analysis_run_id)
|
||||||
result = await generate_report(analysis_run_id)
|
result = await generate_report(analysis_run_id)
|
||||||
|
result = _patch_report(result, await _build_overrides(analysis_run_id))
|
||||||
await save_analysis_report(analysis_run_id, result.model_dump())
|
await save_analysis_report(analysis_run_id, result.model_dump())
|
||||||
logger.info("[report] done run=%s", analysis_run_id)
|
logger.info("[report] done run=%s", analysis_run_id)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue