diff --git a/docs/guides/browse_sh_crawler_playbook.md b/docs/guides/browse_sh_crawler_playbook.md index b0a1381..6dcd39c 100644 --- a/docs/guides/browse_sh_crawler_playbook.md +++ b/docs/guides/browse_sh_crawler_playbook.md @@ -80,6 +80,13 @@ python scripts/ops/report_pixelrag_crawler_integration.py \ --tile-size tile=512x512 ``` +登入後 API 回讀: + +```text +/api/ai-automation/pixelrag-crawler-integration?platform=momo +/api/ai-automation/pixelrag-crawler-integration?platform=pchome&manifest_url=https://24h.pchome.com.tw/prod/TEST-000000001&crawler=PChomeCrawler.search_products&trigger_reason=parser_empty +``` + 安全邊界: - read-only;不登入、不下單、不加入購物車、不寫第三方狀態。 diff --git a/routes/system_public_routes.py b/routes/system_public_routes.py index eda04d4..7cce203 100644 --- a/routes/system_public_routes.py +++ b/routes/system_public_routes.py @@ -634,6 +634,31 @@ def ai_automation_sitewide_visual_qa_readback_api(): return jsonify(build_sitewide_visual_qa_readback(max_age_hours=max(1, min(max_age_hours or 26, 168)))) +@system_public_bp.route('/api/ai-automation/pixelrag-crawler-integration') +@login_required +def ai_automation_pixelrag_crawler_integration_api(): + """Read-only PixelRAG-style crawler visual evidence assessment.""" + from services.pixelrag_crawler_integration_service import ( + build_pixelrag_crawler_integration_assessment, + build_pixelrag_visual_evidence_manifest, + ) + + platforms = request.args.getlist('platform') or None + manifest_url = str(request.args.get('manifest_url') or '').strip() + if manifest_url: + platform = (platforms or ['momo'])[0] + return jsonify(build_pixelrag_visual_evidence_manifest( + url=manifest_url, + platform=platform, + crawler=str(request.args.get('crawler') or 'crawler_diagnostics'), + trigger_reason=str(request.args.get('trigger_reason') or 'parser_empty_or_low_confidence'), + evidence_intent=str(request.args.get('evidence_intent') or 'recover_visual_offer_evidence'), + )) + return jsonify(build_pixelrag_crawler_integration_assessment( + target_platforms=tuple(platforms) if platforms else None, + )) + + @system_public_bp.route('/api/ai-automation/smoke/history/export') @login_required def ai_automation_smoke_history_export(): diff --git a/tests/test_pixelrag_crawler_integration_service.py b/tests/test_pixelrag_crawler_integration_service.py index bacb18c..4d7f5ad 100644 --- a/tests/test_pixelrag_crawler_integration_service.py +++ b/tests/test_pixelrag_crawler_integration_service.py @@ -197,3 +197,32 @@ def test_pixelrag_report_cli_outputs_visual_manifest(): assert payload["result"] == "PIXELRAG_VISUAL_EVIDENCE_MANIFEST_READY" assert payload["capture_target"]["platform"] == "pchome" assert payload["tile_plan"]["tile_count"] == 4 + + +def test_pixelrag_ai_automation_route_returns_assessment_and_manifest(): + from flask import Flask + from routes import system_public_routes as routes + + app = Flask(__name__) + with app.test_request_context( + "/api/ai-automation/pixelrag-crawler-integration?platform=momo" + ): + assessment_response = routes.ai_automation_pixelrag_crawler_integration_api.__wrapped__() + assessment = assessment_response.get_json() + + with app.test_request_context( + "/api/ai-automation/pixelrag-crawler-integration" + "?platform=pchome" + "&manifest_url=https://24h.pchome.com.tw/prod/TEST-000000001" + "&crawler=PChomeCrawler.search_products" + "&trigger_reason=parser_empty" + ): + manifest_response = routes.ai_automation_pixelrag_crawler_integration_api.__wrapped__() + manifest = manifest_response.get_json() + + assert assessment["policy"] == "read_only_pixelrag_crawler_integration_assessment_v1" + assert assessment["target_platforms"] == ["momo"] + assert assessment["controlled_apply"]["db_write"] is False + assert manifest["policy"] == "read_only_pixelrag_visual_evidence_manifest_v1" + assert manifest["result"] == "PIXELRAG_VISUAL_EVIDENCE_MANIFEST_READY" + assert manifest["capture_target"]["platform"] == "pchome"