"""启动确认窗兜底样本内部上报端点(pricebot → app-server)。 pricebot 的 launch_confirm_agent 每次靠 LLM 兜底放行一个"静态 PROFILES 没认出"的跨 App 启动确认窗时,把完整样本 POST 到这里落库。**不是给客户端的接口**:不走用户 JWT,靠 server 间共享密钥头 `X-Internal-Secret` 校验(== settings.INTERNAL_API_SECRET)。密钥未配置 (默认空)时直接 503,避免裸奔写端点。 研发定期人工把 exec_success=true 的样本沉淀进 pricebot 的 launch_confirm.PROFILES。 """ from __future__ import annotations import hmac import logging from typing import Annotated from fastapi import APIRouter, Header, HTTPException, status from app.api.deps import DbSession from app.core.config import settings from app.repositories import launch_confirm_sample as repo from app.schemas.launch_confirm_sample import ( LaunchConfirmSampleIn, LaunchConfirmSampleOut, ) logger = logging.getLogger("shagua.internal.launch_confirm") router = APIRouter(prefix="/internal", tags=["internal"]) def _check_secret(x_internal_secret: str | None) -> None: """共享密钥校验。未配置 → 503(挡裸奔写端点);不匹配 → 401(常量时间比较)。""" configured = settings.INTERNAL_API_SECRET if not configured: raise HTTPException( status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="internal api not configured", ) if not x_internal_secret or not hmac.compare_digest(x_internal_secret, configured): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid internal secret", ) @router.post( "/launch-confirm-sample", response_model=LaunchConfirmSampleOut, summary="启动确认窗兜底样本上报(pricebot→app-server,落 launch_confirm_sample)", ) def report_launch_confirm_sample( payload: LaunchConfirmSampleIn, db: DbSession, x_internal_secret: Annotated[str | None, Header()] = None, ) -> LaunchConfirmSampleOut: _check_secret(x_internal_secret) sid = repo.insert_sample(db, payload) logger.info( "launch_confirm_sample id=%d host=%s locale=%s success=%s trace=%s", sid, payload.host_package, payload.system_locale, payload.exec_success, payload.trace_id, ) return LaunchConfirmSampleOut(id=sid)