import logging import uuid6 from fastapi import APIRouter, BackgroundTasks, Depends, status, HTTPException from common.deps import verify_api_key from common.db import fetchone, insert_instagram_row, insert_facebook_row, insert_naver_blog_row, insert_youtube_row, insert_gangnam_unni_row, insert_analysis_run from models.analysis import AnalysisCreate, AnalysisStartResponse, AnalysisStatusResponse from models.status import AnalysisStatus from services.pipeline import run_pipeline router = APIRouter(prefix="/api/analysis", tags=["analysis"], dependencies=[Depends(verify_api_key)]) logger = logging.getLogger(__name__) @router.post("", status_code=status.HTTP_202_ACCEPTED, response_model=AnalysisStartResponse) async def start_analysis(body: AnalysisCreate, background_tasks: BackgroundTasks): logger.info("POST /api/analysis clinic_id=%s", body.clinic_id) analysis_run_id = str(uuid6.uuid7()) hospital_id = body.clinic_id # 사실 hospital과 owner_user_id 비교 후 검증이 필요한 거지만 일단 PoC 니까. 나중에 바꿉니다. hospital = await fetchone( "SELECT owner_user_id, url FROM hospital_baseinfo WHERE hospital_id = %s", (hospital_id,), ) if not hospital: raise HTTPException(status_code=409, detail="Clinic not found") ig_id = await insert_instagram_row(hospital_id, body.channels.instagram) if body.channels.instagram else None fb_id = await insert_facebook_row(hospital_id, body.channels.facebook) if body.channels.facebook else None nb_id = await insert_naver_blog_row(hospital_id, body.channels.naver_blog) if body.channels.naver_blog else None yt_id = await insert_youtube_row(hospital_id, body.channels.youtube) if body.channels.youtube else None gu_id = await insert_gangnam_unni_row(hospital_id, body.channels.gangnam_unni) if body.channels.gangnam_unni else None analysis_run_id = await insert_analysis_run( analysis_run_id, hospital_id, hospital["owner_user_id"], ig_id, fb_id, nb_id, yt_id, gu_id, ) background_tasks.add_task(run_pipeline, analysis_run_id) return AnalysisStartResponse( analysis_run_id=analysis_run_id, clinic_id=hospital_id, status=AnalysisStatus.DISCOVERING, estimated_seconds=90, poll_url=f"/api/analysis/{analysis_run_id}/status", ) @router.get("/{run_id}/status", response_model=AnalysisStatusResponse) async def get_analysis_status(run_id: str): logger.info("GET /api/analysis/%s/status", run_id) row = await fetchone("SELECT status FROM analysis_runs WHERE analysis_run_id = %s", (run_id,)) if not row: raise HTTPException(status_code=404, detail="Run not found") return AnalysisStatusResponse( analysis_run_id=run_id, status=AnalysisStatus(row["status"]), progress=50.0, current_step="", channel_errors={}, completed_at=None, )