dotb_ai-platform/apps/dev-console/public/lead-scoring-api-docs.html
2026-09-14 09:57:12 +07:00

42 lines
43 KiB
HTML

<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Tài liệu API Lead Scoring Service - AI Platform</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%0A%20%20%20xmlns%3Adc%3D%22http%3A//purl.org/dc/elements/1.1/%22%0A%20%20%20xmlns%3Acc%3D%22http%3A//creativecommons.org/ns%23%22%0A%20%20%20xmlns%3Ardf%3D%22http%3A//www.w3.org/1999/02/22-rdf-syntax-ns%23%22%0A%20%20%20xmlns%3Asvg%3D%22http%3A//www.w3.org/2000/svg%22%0A%20%20%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%0A%20%20%20viewBox%3D%220%200%20566.92932%20566.92932%22%0A%20%20%20height%3D%22566.92932%22%0A%20%20%20width%3D%22566.92932%22%0A%20%20%20xml%3Aspace%3D%22preserve%22%0A%20%20%20id%3D%22svg2%22%0A%20%20%20version%3D%221.1%22%3E%3Cmetadata%0A%20%20%20%20%20id%3D%22metadata8%22%3E%3Crdf%3ARDF%3E%3Ccc%3AWork%0A%20%20%20%20%20%20%20%20%20rdf%3Aabout%3D%22%22%3E%3Cdc%3Aformat%3Eimage/svg%2Bxml%3C/dc%3Aformat%3E%3Cdc%3Atype%0A%20%20%20%20%20%20%20%20%20%20%20rdf%3Aresource%3D%22http%3A//purl.org/dc/dcmitype/StillImage%22%20/%3E%3C/cc%3AWork%3E%3C/rdf%3ARDF%3E%3C/metadata%3E%3Cdefs%0A%20%20%20%20%20id%3D%22defs6%22%3E%3ClinearGradient%0A%20%20%20%20%20%20%20id%3D%22linearGradient28%22%0A%20%20%20%20%20%20%20spreadMethod%3D%22pad%22%0A%20%20%20%20%20%20%20gradientTransform%3D%22matrix%28261.43005%2C0%2C0%2C-261.43005%2C107.24294%2C217.74225%29%22%0A%20%20%20%20%20%20%20gradientUnits%3D%22userSpaceOnUse%22%0A%20%20%20%20%20%20%20y2%3D%220%22%0A%20%20%20%20%20%20%20x2%3D%221%22%0A%20%20%20%20%20%20%20y1%3D%220%22%0A%20%20%20%20%20%20%20x1%3D%220%22%3E%3Cstop%0A%20%20%20%20%20%20%20%20%20id%3D%22stop24%22%0A%20%20%20%20%20%20%20%20%20offset%3D%220%22%0A%20%20%20%20%20%20%20%20%20style%3D%22stop-opacity%3A1%3Bstop-color%3A%2300c9fd%22%20/%3E%3Cstop%0A%20%20%20%20%20%20%20%20%20id%3D%22stop26%22%0A%20%20%20%20%20%20%20%20%20offset%3D%221%22%0A%20%20%20%20%20%20%20%20%20style%3D%22stop-opacity%3A1%3Bstop-color%3A%2381ee8e%22%20/%3E%3C/linearGradient%3E%3ClinearGradient%0A%20%20%20%20%20%20%20id%3D%22linearGradient48%22%0A%20%20%20%20%20%20%20spreadMethod%3D%22pad%22%0A%20%20%20%20%20%20%20gradientTransform%3D%22matrix%2886.359985%2C0%2C0%2C-86.359985%2C63.88295%2C136.00223%29%22%0A%20%20%20%20%20%20%20gradientUnits%3D%22userSpaceOnUse%22%0A%20%20%20%20%20%20%20y2%3D%220%22%0A%20%20%20%20%20%20%20x2%3D%221%22%0A%20%20%20%20%20%20%20y1%3D%220%22%0A%20%20%20%20%20%20%20x1%3D%220%22%3E%3Cstop%0A%20%20%20%20%20%20%20%20%20id%3D%22stop44%22%0A%20%20%20%20%20%20%20%20%20offset%3D%220%22%0A%20%20%20%20%20%20%20%20%20style%3D%22stop-opacity%3A1%3Bstop-color%3A%23ae3ba4%22%20/%3E%3Cstop%0A%20%20%20%20%20%20%20%20%20id%3D%22stop46%22%0A%20%20%20%20%20%20%20%20%20offset%3D%221%22%0A%20%20%20%20%20%20%20%20%20style%3D%22stop-opacity%3A1%3Bstop-color%3A%23ed0a04%22%20/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg%0A%20%20%20%20%20transform%3D%22matrix%281.3333333%2C0%2C0%2C-1.3333333%2C0%2C566.92933%29%22%0A%20%20%20%20%20id%3D%22g10%22%3E%3Cg%0A%20%20%20%20%20%20%20id%3D%22g12%22%3E%3Cg%0A%20%20%20%20%20%20%20%20%20id%3D%22g14%22%3E%3Cg%0A%20%20%20%20%20%20%20%20%20%20%20id%3D%22g20%22%3E%3Cg%0A%20%20%20%20%20%20%20%20%20%20%20%20%20id%3D%22g22%22%3E%3Cpath%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id%3D%22path30%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20style%3D%22fill%3Aurl%28%23linearGradient28%29%3Bstroke%3Anone%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20d%3D%22m%20107.243%2C404.187%20v%20-208.48%20c%2032.89%2C-0.1%2059.53%2C-26.79%2059.53%2C-59.7%20v%200%20c%200%2C-23.269%20-13.32%2C-43.43%20-32.75%2C-53.28%20v%200%20c%2023.88%2C-31.26%2061.55%2C-51.43%20103.93%2C-51.43%20v%200%20c%2034.67%2C0%2067.92%2C13.771%2092.43%2C38.28%20v%200%20c%2024.519%2C24.51%2038.289%2C57.76%2038.289%2C92.429%20v%200%20c%200%2C34.672%20-13.77%2C67.922%20-38.289%2C92.431%20v%200%20c%20-24.51%2C24.51%20-57.76%2C38.28%20-92.43%2C38.28%20v%200%20c%20-21.08%2C-0.02%20-41.85%2C-5.14%20-60.531%2C-14.93%20v%200%20126.4%20z%20m%2067.98%2C-241.81%20c%200%2C34.32%2027.82%2C62.15%2062.15%2C62.15%20v%200%20c%2034.32%2C0%2062.14%2C-27.83%2062.14%2C-62.15%20v%200%20c%200%2C-34.32%20-27.82%2C-62.139%20-62.14%2C-62.139%20v%200%20c%20-34.33%2C0%20-62.15%2C27.819%20-62.15%2C62.139%22%20/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg%0A%20%20%20%20%20%20%20id%3D%22g32%22%3E%3Cg%0A%20%20%20%20%20%20%20%20%20id%3D%22g34%22%3E%3Cg%0A%20%20%20%20%20%20%20%20%20%20%20id%3D%22g40%22%3E%3Cg%0A%20%20%20%20%20%20%20%20%20%20%20%20%20id%3D%22g42%22%3E%3Cpath%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20id%3D%22path50%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20style%3D%22fill%3Aurl%28%23linearGradient48%29%3Bstroke%3Anone%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20d%3D%22m%2063.883%2C136.007%20c%200%2C-23.85%2019.34%2C-43.18%2043.18%2C-43.18%20v%200%20c%206.31%2C0%2012.3%2C1.351%2017.7%2C3.78%20v%200%20c%2015.02%2C6.76%2025.48%2C21.861%2025.48%2C39.4%20v%200%20c%200%2C23.36%20-18.551%2C42.38%20-41.73%2C43.15%20v%200%20c%20-0.48%2C0.01%20-0.97%2C0.02%20-1.45%2C0.02%20v%200%20c%20-23.84%2C0%20-43.18%2C-19.33%20-43.18%2C-43.17%22%20/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
<style>
body { margin: 0; padding: 0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
</style>
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
</head>
<body>
<div id="redoc-container"></div>
<script>
const spec = {"components": {"schemas": {"AiMetadataFailure": {"additionalProperties": false, "properties": {"detail": {"description": "AI error detail", "maxLength": 255, "minLength": 1, "title": "Detail", "type": "string"}, "error_code": {"description": "Machine-readable AI error code", "maxLength": 64, "minLength": 1, "title": "Error Code", "type": "string"}, "fallback_policy": {"$ref": "#/components/schemas/FallbackPolicy", "description": "Fallback policy triggered"}}, "required": ["error_code", "detail", "fallback_policy"], "title": "AiMetadataFailure", "type": "object"}, "AiMetadataSuccess": {"additionalProperties": false, "properties": {"effort_profile": {"$ref": "#/components/schemas/EffortProfile", "description": "AI effort profile applied"}, "model": {"description": "AI model used", "maxLength": 64, "minLength": 1, "title": "Model", "type": "string"}, "pass_count": {"description": "Number of passes executed", "minimum": 1.0, "title": "Pass Count", "type": "integer"}}, "required": ["model", "effort_profile", "pass_count"], "title": "AiMetadataSuccess", "type": "object"}, "ApproveReviewRequest": {"additionalProperties": false, "properties": {"decision": {"const": "approve", "default": "approve", "description": "Approve calculated score", "title": "Decision", "type": "string"}, "expected_run_version": {"description": "Expected run version for optimistic concurrency", "minimum": 1.0, "title": "Expected Run Version", "type": "integer"}, "note": {"anyOf": [{"maxLength": 2000, "type": "string"}, {"type": "null"}], "description": "Optional reviewer note or reason", "title": "Note"}, "reviewer": {"$ref": "#/components/schemas/ReviewerContext", "description": "Caller-provided reviewer authorization context"}}, "required": ["expected_run_version", "reviewer"], "title": "ApproveReviewRequest", "type": "object"}, "CanonicalSnapshot": {"properties": {"captured_at": {"description": "Timezone-aware timestamp when snapshot evidence was frozen", "format": "date-time", "title": "Captured At", "type": "string"}, "conversations": {"items": {"$ref": "#/components/schemas/ConversationEvidence"}, "title": "Conversations", "type": "array"}, "hitl_policy": {"anyOf": [{"$ref": "#/components/schemas/HitlPolicy"}, {"type": "null"}]}, "identity_context": {"anyOf": [{"$ref": "#/components/schemas/IdentityContext"}, {"type": "null"}]}, "lead_profile": {"$ref": "#/components/schemas/LeadProfile"}, "scope": {"$ref": "#/components/schemas/SnapshotScope", "default": "linked_contact_history"}, "trigger_metadata": {"anyOf": [{"$ref": "#/components/schemas/TriggerMetadata"}, {"type": "null"}]}, "truncation": {"anyOf": [{"$ref": "#/components/schemas/TruncationMetadata"}, {"type": "null"}]}, "version": {"default": "1.0.0", "maxLength": 64, "title": "Version", "type": "string"}}, "required": ["captured_at", "lead_profile"], "title": "CanonicalSnapshot", "type": "object"}, "ConversationEvidence": {"properties": {"assigned_agent_id": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Assigned Agent Id"}, "channel": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "title": "Channel"}, "conversation_id": {"maxLength": 255, "minLength": 1, "title": "Conversation Id", "type": "string"}, "messages": {"items": {"$ref": "#/components/schemas/MessageEvidence"}, "title": "Messages", "type": "array"}}, "required": ["conversation_id"], "title": "ConversationEvidence", "type": "object"}, "CreateScoringRunRequest": {"properties": {"scoring_config_version": {"default": "1.0.0", "description": "Scoring config version", "maxLength": 64, "minLength": 1, "title": "Scoring Config Version", "type": "string"}, "snapshot": {"$ref": "#/components/schemas/CanonicalSnapshot", "description": "Canonical Lead Snapshot containing evidence"}, "subject_ref": {"description": "EMS Lead reference or identifier", "maxLength": 255, "minLength": 1, "title": "Subject Ref", "type": "string"}, "tenant_id": {"description": "Tenant identifier", "maxLength": 255, "minLength": 1, "title": "Tenant Id", "type": "string"}}, "required": ["tenant_id", "subject_ref", "snapshot"], "title": "CreateScoringRunRequest", "type": "object"}, "CreateScoringRunResponse": {"properties": {"created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "run_id": {"description": "Server-generated unique scoring run ID", "maxLength": 36, "title": "Run Id", "type": "string"}, "scoring_config_version": {"description": "Scoring config version applied", "maxLength": 64, "title": "Scoring Config Version", "type": "string"}, "status": {"$ref": "#/components/schemas/ScoringRunStatus", "default": "pending", "description": "Initial run status"}, "status_url": {"description": "URL to inspect scoring run status", "title": "Status Url", "type": "string"}, "subject_ref": {"description": "EMS Lead reference", "maxLength": 255, "title": "Subject Ref", "type": "string"}, "tenant_id": {"description": "Tenant identifier", "maxLength": 255, "title": "Tenant Id", "type": "string"}}, "required": ["run_id", "status_url", "tenant_id", "subject_ref", "scoring_config_version", "created_at"], "title": "CreateScoringRunResponse", "type": "object"}, "EffortProfile": {"enum": ["light", "medium", "heavy"], "title": "EffortProfile", "type": "string"}, "ErrorResponse": {"properties": {"detail": {"description": "Human-readable error description", "title": "Detail", "type": "string"}, "error_code": {"description": "Machine-readable error code", "title": "Error Code", "type": "string"}}, "required": ["error_code", "detail"], "title": "ErrorResponse", "type": "object"}, "FallbackPolicy": {"enum": ["rules_only_review", "fail_run"], "title": "FallbackPolicy", "type": "string"}, "HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "title": "Detail", "type": "array"}}, "title": "HTTPValidationError", "type": "object"}, "HealthResponse": {"additionalProperties": false, "properties": {"database": {"default": "connected", "enum": ["connected", "unreachable", "unconfigured"], "title": "Database", "type": "string"}, "status": {"default": "ok", "enum": ["ok", "unhealthy"], "title": "Status", "type": "string"}, "version": {"default": "0.1.0", "title": "Version", "type": "string"}}, "title": "HealthResponse", "type": "object"}, "HitlPolicy": {"properties": {"confidence_threshold": {"default": 0.8, "maximum": 1.0, "minimum": 0.0, "title": "Confidence Threshold", "type": "number"}, "policy_version": {"default": "1.0.0", "maxLength": 64, "title": "Policy Version", "type": "string"}}, "title": "HitlPolicy", "type": "object"}, "IdentityContext": {"properties": {"contact_id": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Contact Id"}, "details": {"additionalProperties": true, "title": "Details", "type": "object"}, "match_quality": {"anyOf": [{"enum": ["direct", "phone_and_email", "phone_and_name", "phone_only"], "type": "string"}, {"type": "null"}], "title": "Match Quality"}}, "title": "IdentityContext", "type": "object"}, "LeadProfile": {"properties": {"custom_fields": {"additionalProperties": true, "title": "Custom Fields", "type": "object"}, "email": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Email"}, "ems_lead_id": {"maxLength": 255, "minLength": 1, "title": "Ems Lead Id", "type": "string"}, "name": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Name"}, "phone": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "title": "Phone"}, "status": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "title": "Status"}}, "required": ["ems_lead_id"], "title": "LeadProfile", "type": "object"}, "MessageEvidence": {"properties": {"content": {"minLength": 1, "title": "Content", "type": "string"}, "message_id": {"maxLength": 255, "minLength": 1, "title": "Message Id", "type": "string"}, "sender_type": {"$ref": "#/components/schemas/MessageSenderType"}, "sent_at": {"description": "Timezone-aware timestamp of when message was sent", "format": "date-time", "title": "Sent At", "type": "string"}}, "required": ["message_id", "sender_type", "content", "sent_at"], "title": "MessageEvidence", "type": "object"}, "MessageSenderType": {"enum": ["contact", "agent", "bot"], "type": "string"}, "OverrideReviewRequest": {"additionalProperties": false, "properties": {"decision": {"const": "override", "default": "override", "description": "Override score", "title": "Decision", "type": "string"}, "expected_run_version": {"description": "Expected run version for optimistic concurrency", "minimum": 1.0, "title": "Expected Run Version", "type": "integer"}, "note": {"anyOf": [{"maxLength": 2000, "type": "string"}, {"type": "null"}], "description": "Optional reviewer note or reason", "title": "Note"}, "override_score": {"description": "Human override score between 0 and 100", "maximum": 100.0, "minimum": 0.0, "title": "Override Score", "type": "integer"}, "reviewer": {"$ref": "#/components/schemas/ReviewerContext", "description": "Caller-provided reviewer authorization context"}}, "required": ["expected_run_version", "reviewer", "override_score"], "title": "OverrideReviewRequest", "type": "object"}, "ReEvaluateReviewRequest": {"additionalProperties": false, "properties": {"decision": {"const": "re_evaluate", "default": "re_evaluate", "description": "Re-evaluate with new snapshot and create child run", "title": "Decision", "type": "string"}, "expected_run_version": {"description": "Expected run version for optimistic concurrency", "minimum": 1.0, "title": "Expected Run Version", "type": "integer"}, "note": {"anyOf": [{"maxLength": 2000, "type": "string"}, {"type": "null"}], "description": "Optional reviewer note or reason", "title": "Note"}, "reviewer": {"$ref": "#/components/schemas/ReviewerContext", "description": "Caller-provided reviewer authorization context"}, "snapshot": {"$ref": "#/components/schemas/CanonicalSnapshot", "description": "New Canonical Lead Snapshot containing updated evidence"}}, "required": ["expected_run_version", "reviewer", "snapshot"], "title": "ReEvaluateReviewRequest", "type": "object"}, "ReviewDecision": {"enum": ["approve", "override", "re_evaluate"], "title": "ReviewDecision", "type": "string"}, "ReviewResponse": {"additionalProperties": false, "properties": {"calculated_score": {"anyOf": [{"maximum": 100.0, "minimum": 0.0, "type": "integer"}, {"type": "null"}], "description": "Original calculated score", "title": "Calculated Score"}, "child_run_id": {"anyOf": [{"maxLength": 36, "type": "string"}, {"type": "null"}], "description": "Server-generated child scoring run ID when decision is re_evaluate", "title": "Child Run Id"}, "decision": {"$ref": "#/components/schemas/ReviewDecision", "description": "Review decision applied"}, "effective_score": {"anyOf": [{"maximum": 100.0, "minimum": 0.0, "type": "integer"}, {"type": "null"}], "description": "Effective score after review", "title": "Effective Score"}, "note": {"anyOf": [{"maxLength": 2000, "type": "string"}, {"type": "null"}], "description": "Reviewer note", "title": "Note"}, "reviewed_at": {"description": "Timestamp of review", "format": "date-time", "title": "Reviewed At", "type": "string"}, "reviewed_by": {"description": "Actor ID who reviewed", "maxLength": 255, "title": "Reviewed By", "type": "string"}, "run_id": {"description": "Scoring run ID", "maxLength": 36, "title": "Run Id", "type": "string"}, "status": {"$ref": "#/components/schemas/ScoringRunStatus", "description": "Updated run status (completed or superseded)"}, "subject_ref": {"description": "EMS Lead reference", "maxLength": 255, "title": "Subject Ref", "type": "string"}, "tenant_id": {"description": "Tenant identifier", "maxLength": 255, "title": "Tenant Id", "type": "string"}, "version": {"description": "New run version after review", "minimum": 1.0, "title": "Version", "type": "integer"}}, "required": ["run_id", "tenant_id", "subject_ref", "status", "decision", "version", "reviewed_by", "reviewed_at"], "title": "ReviewResponse", "type": "object"}, "ReviewerContext": {"additionalProperties": false, "properties": {"actor_id": {"description": "Actor identifier of the reviewer", "maxLength": 255, "minLength": 1, "title": "Actor Id", "type": "string"}, "current_assignee_id": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "description": "Caller-supplied assignment context retained for compatibility", "title": "Current Assignee Id"}, "role": {"$ref": "#/components/schemas/ReviewerRole", "description": "Reviewer role supplied by the caller for audit metadata"}}, "required": ["actor_id", "role"], "title": "ReviewerContext", "type": "object"}, "ReviewerRole": {"enum": ["administrator", "agent"], "title": "ReviewerRole", "type": "string"}, "RuleMetric": {"enum": ["profile_field_count", "conversation_count", "message_count"], "title": "RuleMetric", "type": "string"}, "ScoringConfig": {"properties": {"age_primary_max": {"default": 15, "maximum": 100.0, "minimum": 0.0, "title": "Age Primary Max", "type": "integer"}, "age_primary_min": {"default": 3, "maximum": 100.0, "minimum": 0.0, "title": "Age Primary Min", "type": "integer"}, "age_primary_points": {"default": 40, "maximum": 100.0, "minimum": 0.0, "title": "Age Primary Points", "type": "integer"}, "age_secondary_max": {"default": 18, "maximum": 100.0, "minimum": 0.0, "title": "Age Secondary Max", "type": "integer"}, "age_secondary_min": {"default": 16, "maximum": 100.0, "minimum": 0.0, "title": "Age Secondary Min", "type": "integer"}, "age_secondary_points": {"default": 20, "maximum": 100.0, "minimum": 0.0, "title": "Age Secondary Points", "type": "integer"}, "ai_model": {"default": "openai/gpt-4o-mini", "maxLength": 64, "minLength": 1, "title": "Ai Model", "type": "string"}, "ai_timeout_seconds": {"default": 10.0, "exclusiveMinimum": 0.0, "title": "Ai Timeout Seconds", "type": "number"}, "ai_weight": {"default": 0.6, "maximum": 1.0, "minimum": 0.0, "title": "Ai Weight", "type": "number"}, "base_score": {"default": 0, "maximum": 100.0, "minimum": 0.0, "title": "Base Score", "type": "integer"}, "completeness_threshold": {"default": 0.5, "maximum": 1.0, "minimum": 0.0, "title": "Completeness Threshold", "type": "number"}, "confidence": {"maximum": 1.0, "minimum": 0.0, "title": "Confidence", "type": "number"}, "confidence_threshold": {"maximum": 1.0, "minimum": 0.0, "title": "Confidence Threshold", "type": "number"}, "education_demo_enabled": {"default": false, "title": "Education Demo Enabled", "type": "boolean"}, "effort_profile": {"$ref": "#/components/schemas/EffortProfile", "default": "medium"}, "fallback_policy": {"$ref": "#/components/schemas/FallbackPolicy", "default": "rules_only_review"}, "hitl_policy_version": {"maxLength": 64, "minLength": 1, "title": "Hitl Policy Version", "type": "string"}, "medium_extract_prompt": {"default": "Bạn là trợ lý AI phân tích hội thoại để đánh giá tiềm năng học viên. Hãy trích xuất bằng chứng có cấu trúc về nhu cầu khóa học, mức độ quan tâm, thời điểm đăng ký và rào cản. Trả lời bằng tiếng Việt và không tự bịa dữ kiện.", "description": "Editable system prompt for Medium AI evidence extraction pass", "maxLength": 4000, "minLength": 1, "title": "Medium Extract Prompt", "type": "string"}, "medium_score_prompt": {"default": "Bạn là chuyên gia chấm điểm Lead giáo dục từ 0 đến 100. Dựa trên bằng chứng đã trích xuất, hãy đánh giá khả năng đăng ký, độ tin cậy, lý do và các yếu tố tích cực hoặc tiêu cực. Trả lời bằng tiếng Việt và không tự bịa dữ kiện.", "description": "Editable system prompt for Medium AI lead scoring pass", "maxLength": 4000, "minLength": 1, "title": "Medium Score Prompt", "type": "string"}, "recency_cold_max_days": {"default": 30, "minimum": 0.0, "title": "Recency Cold Max Days", "type": "number"}, "recency_cold_points": {"default": 5, "maximum": 100.0, "minimum": 0.0, "title": "Recency Cold Points", "type": "integer"}, "recency_cool_max_days": {"default": 14, "minimum": 0.0, "title": "Recency Cool Max Days", "type": "number"}, "recency_cool_points": {"default": 15, "maximum": 100.0, "minimum": 0.0, "title": "Recency Cool Points", "type": "integer"}, "recency_hot_max_days": {"default": 3, "minimum": 0.0, "title": "Recency Hot Max Days", "type": "number"}, "recency_hot_points": {"default": 40, "maximum": 100.0, "minimum": 0.0, "title": "Recency Hot Points", "type": "integer"}, "recency_warm_max_days": {"default": 7, "minimum": 0.0, "title": "Recency Warm Max Days", "type": "number"}, "recency_warm_points": {"default": 25, "maximum": 100.0, "minimum": 0.0, "title": "Recency Warm Points", "type": "integer"}, "rule_weight": {"default": 0.4, "maximum": 1.0, "minimum": 0.0, "title": "Rule Weight", "type": "number"}, "rules": {"default": [], "items": {"$ref": "#/components/schemas/ScoringRule"}, "title": "Rules", "type": "array"}, "source_call_in_points": {"default": 15, "maximum": 100.0, "minimum": 0.0, "title": "Source Call In Points", "type": "integer"}, "source_campaign_points": {"default": 8, "maximum": 100.0, "minimum": 0.0, "title": "Source Campaign Points", "type": "integer"}, "source_digital_points": {"default": 10, "maximum": 100.0, "minimum": 0.0, "title": "Source Digital Points", "type": "integer"}, "source_other_points": {"default": 5, "maximum": 100.0, "minimum": 0.0, "title": "Source Other Points", "type": "integer"}, "source_referral_points": {"default": 20, "maximum": 100.0, "minimum": 0.0, "title": "Source Referral Points", "type": "integer"}, "version": {"maxLength": 64, "minLength": 1, "title": "Version", "type": "string"}}, "required": ["version", "confidence", "confidence_threshold", "hitl_policy_version"], "title": "ScoringConfig", "type": "object"}, "ScoringMode": {"enum": ["light_ai", "medium_ai", "heavy_ai", "rules_only_fallback", "rule_only"], "title": "ScoringMode", "type": "string"}, "ScoringRule": {"properties": {"metric": {"$ref": "#/components/schemas/RuleMetric"}, "minimum": {"minimum": 0.0, "title": "Minimum", "type": "integer"}, "points": {"maximum": 100.0, "minimum": -100.0, "title": "Points", "type": "integer"}}, "required": ["metric", "minimum", "points"], "title": "ScoringRule", "type": "object"}, "ScoringRunResponse": {"additionalProperties": false, "properties": {"ai_metadata": {"anyOf": [{"$ref": "#/components/schemas/AiMetadataSuccess"}, {"$ref": "#/components/schemas/AiMetadataFailure"}, {"type": "null"}], "title": "Ai Metadata"}, "ai_score": {"anyOf": [{"maximum": 100.0, "minimum": 0.0, "type": "integer"}, {"type": "null"}], "title": "Ai Score"}, "category": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "description": "Public lead tier / category derived deterministically from score", "title": "Category"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Completed At"}, "confidence": {"anyOf": [{"maximum": 1.0, "minimum": 0.0, "type": "number"}, {"type": "null"}], "title": "Confidence"}, "confidence_threshold": {"anyOf": [{"maximum": 1.0, "minimum": 0.0, "type": "number"}, {"type": "null"}], "title": "Confidence Threshold"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "degraded": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Degraded"}, "effective_config": {"anyOf": [{"$ref": "#/components/schemas/ScoringConfig"}, {"type": "null"}]}, "effective_score": {"anyOf": [{"maximum": 100.0, "minimum": 0.0, "type": "integer"}, {"type": "null"}], "title": "Effective Score"}, "error_code": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "title": "Error Code"}, "explanation": {"anyOf": [{"maxLength": 1000, "type": "string"}, {"type": "null"}], "description": "Concise public explanation using AI reasoning where available or rule summary", "title": "Explanation"}, "final_score": {"anyOf": [{"maximum": 100.0, "minimum": 0.0, "type": "integer"}, {"type": "null"}], "title": "Final Score"}, "parent_run_id": {"anyOf": [{"maxLength": 36, "type": "string"}, {"type": "null"}], "description": "Parent scoring run ID if created via re-evaluation", "title": "Parent Run Id"}, "recommended_action": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "description": "Deterministic recommended next action based on score", "title": "Recommended Action"}, "retryable": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Retryable"}, "rule_score": {"anyOf": [{"maximum": 100.0, "minimum": 0.0, "type": "integer"}, {"type": "null"}], "title": "Rule Score"}, "run_id": {"description": "Unique scoring run ID", "maxLength": 36, "title": "Run Id", "type": "string"}, "scoring_config_version": {"description": "Scoring config version", "maxLength": 64, "title": "Scoring Config Version", "type": "string"}, "scoring_mode": {"anyOf": [{"$ref": "#/components/schemas/ScoringMode"}, {"type": "null"}]}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "status": {"$ref": "#/components/schemas/ScoringRunStatus", "description": "Current scoring run status"}, "subject_ref": {"description": "EMS Lead reference", "maxLength": 255, "title": "Subject Ref", "type": "string"}, "tenant_id": {"description": "Tenant identifier", "maxLength": 255, "title": "Tenant Id", "type": "string"}, "updated_at": {"description": "Last updated timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "version": {"description": "Run version for optimistic concurrency", "minimum": 1.0, "title": "Version", "type": "integer"}}, "required": ["run_id", "tenant_id", "subject_ref", "scoring_config_version", "status", "rule_score", "ai_score", "final_score", "effective_score", "scoring_mode", "degraded", "ai_metadata", "confidence", "confidence_threshold", "effective_config", "error_code", "retryable", "version", "started_at", "completed_at", "created_at", "updated_at"], "title": "ScoringRunResponse", "type": "object"}, "ScoringRunStatus": {"enum": ["pending", "running", "completed", "review_required", "failed", "superseded"], "title": "ScoringRunStatus", "type": "string"}, "SnapshotScope": {"enum": ["trigger_only", "linked_contact_history", "multi_source_history"], "title": "SnapshotScope", "type": "string"}, "TriggerMetadata": {"properties": {"actor_id": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Actor Id"}, "trigger_conversation_id": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Trigger Conversation Id"}, "trigger_type": {"default": "manual_omni", "enum": ["manual_omni", "captain_tool", "dev_console"], "title": "Trigger Type", "type": "string"}}, "title": "TriggerMetadata", "type": "object"}, "TruncationMetadata": {"properties": {"dropped_conversations_count": {"default": 0, "minimum": 0.0, "title": "Dropped Conversations Count", "type": "integer"}, "dropped_messages_count": {"default": 0, "minimum": 0.0, "title": "Dropped Messages Count", "type": "integer"}, "reason": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Reason"}, "truncated": {"default": false, "title": "Truncated", "type": "boolean"}}, "title": "TruncationMetadata", "type": "object"}, "ValidationError": {"properties": {"ctx": {"title": "Context", "type": "object"}, "input": {"title": "Input"}, "loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "title": "Location", "type": "array"}, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}}, "required": ["loc", "msg", "type"], "title": "ValidationError", "type": "object"}}, "securitySchemes": {"HTTPBearer": {"description": "Bearer service token for machine caller authentication", "scheme": "bearer", "type": "http"}}}, "info": {"description": "Lead Scoring service for AI Platform", "title": "Lead Scoring Service", "version": "0.1.0"}, "openapi": "3.1.0", "paths": {"/health": {"get": {"operationId": "health_check_health_get", "responses": {"200": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HealthResponse"}}}, "description": "Service and database healthy"}, "503": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HealthResponse"}}}, "description": "Database or critical dependency unreachable or unconfigured"}}, "summary": "Service Health Check", "tags": ["System"]}}, "/v1/scoring-runs": {"get": {"operationId": "list_scoring_runs_v1_scoring_runs_get", "parameters": [{"description": "Maximum number of recent runs to return", "in": "query", "name": "limit", "required": false, "schema": {"default": 50, "description": "Maximum number of recent runs to return", "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer"}}, {"description": "Tenant identifier for scoped tenant isolation query", "in": "header", "name": "X-Tenant-Id", "required": true, "schema": {"description": "Tenant identifier for scoped tenant isolation query", "maxLength": 255, "minLength": 1, "title": "X-Tenant-Id", "type": "string"}}], "responses": {"200": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScoringRunResponse"}, "title": "Response 200 List Scoring Runs V1 Scoring Runs Get", "type": "array"}}}, "description": "Recent scoring runs scoped to the requested tenant"}, "401": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Invalid or missing Bearer service token"}, "403": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Caller not authorized for tenant"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}, "description": "Validation Error"}}, "security": [{"HTTPBearer": []}], "summary": "List recent Scoring Runs for a tenant", "tags": ["Scoring Runs"]}, "post": {"operationId": "create_scoring_run_v1_scoring_runs_post", "parameters": [{"description": "Tenant AIHub credential passed in RAM for execution attempt", "in": "header", "name": "X-Tenant-VKey", "required": true, "schema": {"description": "Tenant AIHub credential passed in RAM for execution attempt", "maxLength": 1024, "minLength": 1, "title": "X-Tenant-Vkey", "type": "string"}}, {"description": "Tenant-scoped idempotency key", "in": "header", "name": "Idempotency-Key", "required": true, "schema": {"description": "Tenant-scoped idempotency key", "maxLength": 255, "minLength": 1, "title": "Idempotency-Key", "type": "string"}}, {"description": "Originating DotB application identifier", "in": "header", "name": "X-DotB-App", "required": true, "schema": {"description": "Originating DotB application identifier", "maxLength": 64, "minLength": 1, "title": "X-Dotb-App", "type": "string"}}, {"description": "Originating DotB feature identifier", "in": "header", "name": "X-DotB-Feature", "required": true, "schema": {"description": "Originating DotB feature identifier", "maxLength": 64, "minLength": 1, "title": "X-Dotb-Feature", "type": "string"}}], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateScoringRunRequest"}}}, "required": true}, "responses": {"202": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateScoringRunResponse"}}}, "description": "Scoring run accepted and persisted in pending state"}, "401": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Invalid or missing Bearer service token"}, "403": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Caller not authorized for tenant, app, or feature"}, "409": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Idempotency key conflict with mismatched payload"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Validation error or structural caps exceeded"}, "503": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Scoring admission is disabled by the operational kill switch"}}, "security": [{"HTTPBearer": []}], "summary": "Admit a new Lead Scoring Run", "tags": ["Scoring Runs"]}}, "/v1/scoring-runs/configs": {"get": {"operationId": "list_scoring_configs_v1_scoring_runs_configs_get", "parameters": [{"in": "header", "name": "X-Tenant-Id", "required": true, "schema": {"maxLength": 255, "minLength": 1, "title": "X-Tenant-Id", "type": "string"}}, {"in": "header", "name": "X-DotB-App", "required": true, "schema": {"maxLength": 64, "minLength": 1, "title": "X-Dotb-App", "type": "string"}}, {"in": "header", "name": "X-DotB-Feature", "required": true, "schema": {"maxLength": 64, "minLength": 1, "title": "X-Dotb-Feature", "type": "string"}}], "responses": {"200": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScoringConfig"}, "title": "Response List Scoring Configs V1 Scoring Runs Configs Get", "type": "array"}}}, "description": "Successful Response"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}, "description": "Validation Error"}}, "security": [{"HTTPBearer": []}], "summary": "List internal scoring configs", "tags": ["Scoring Runs"]}, "post": {"operationId": "create_scoring_config_v1_scoring_runs_configs_post", "parameters": [{"in": "header", "name": "X-Tenant-Id", "required": true, "schema": {"maxLength": 255, "minLength": 1, "title": "X-Tenant-Id", "type": "string"}}, {"in": "header", "name": "X-DotB-App", "required": true, "schema": {"maxLength": 64, "minLength": 1, "title": "X-Dotb-App", "type": "string"}}, {"in": "header", "name": "X-DotB-Feature", "required": true, "schema": {"maxLength": 64, "minLength": 1, "title": "X-Dotb-Feature", "type": "string"}}], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScoringConfig"}}}, "required": true}, "responses": {"201": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScoringConfig"}}}, "description": "Successful Response"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}, "description": "Validation Error"}}, "security": [{"HTTPBearer": []}], "summary": "Save an immutable internal scoring config", "tags": ["Scoring Runs"]}}, "/v1/scoring-runs/{run_id}": {"get": {"operationId": "get_scoring_run_v1_scoring_runs__run_id__get", "parameters": [{"description": "Scoring run ID", "in": "path", "name": "run_id", "required": true, "schema": {"description": "Scoring run ID", "maxLength": 36, "minLength": 1, "title": "Run Id", "type": "string"}}, {"description": "Tenant identifier for scoped tenant isolation query", "in": "header", "name": "X-Tenant-Id", "required": true, "schema": {"description": "Tenant identifier for scoped tenant isolation query", "maxLength": 255, "minLength": 1, "title": "X-Tenant-Id", "type": "string"}}], "responses": {"200": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScoringRunResponse"}}}, "description": "Scoring run metadata and current status"}, "401": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Invalid or missing Bearer service token"}, "403": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Caller not authorized for tenant"}, "404": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Scoring run not found for tenant"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Validation error for missing required headers"}}, "security": [{"HTTPBearer": []}], "summary": "Inspect Scoring Run status", "tags": ["Scoring Runs"]}}, "/v1/scoring-runs/{run_id}/reviews": {"post": {"operationId": "review_scoring_run_v1_scoring_runs__run_id__reviews_post", "parameters": [{"description": "Scoring run ID", "in": "path", "name": "run_id", "required": true, "schema": {"description": "Scoring run ID", "maxLength": 36, "minLength": 1, "title": "Run Id", "type": "string"}}, {"description": "Tenant identifier for scoped tenant isolation", "in": "header", "name": "X-Tenant-Id", "required": true, "schema": {"description": "Tenant identifier for scoped tenant isolation", "maxLength": 255, "minLength": 1, "title": "X-Tenant-Id", "type": "string"}}, {"description": "Tenant-scoped idempotency key", "in": "header", "name": "Idempotency-Key", "required": true, "schema": {"description": "Tenant-scoped idempotency key", "maxLength": 255, "minLength": 1, "title": "Idempotency-Key", "type": "string"}}, {"description": "Originating DotB application identifier", "in": "header", "name": "X-DotB-App", "required": true, "schema": {"description": "Originating DotB application identifier", "maxLength": 64, "minLength": 1, "title": "X-Dotb-App", "type": "string"}}, {"description": "Originating DotB feature identifier", "in": "header", "name": "X-DotB-Feature", "required": true, "schema": {"description": "Originating DotB feature identifier", "maxLength": 64, "minLength": 1, "title": "X-Dotb-Feature", "type": "string"}}, {"description": "Tenant AIHub credential passed in RAM for execution attempt", "in": "header", "name": "X-Tenant-VKey", "required": false, "schema": {"anyOf": [{"maxLength": 1024, "minLength": 1, "type": "string"}, {"type": "null"}], "description": "Tenant AIHub credential passed in RAM for execution attempt", "title": "X-Tenant-Vkey"}}], "requestBody": {"content": {"application/json": {"schema": {"discriminator": {"mapping": {"approve": "#/components/schemas/ApproveReviewRequest", "override": "#/components/schemas/OverrideReviewRequest", "re_evaluate": "#/components/schemas/ReEvaluateReviewRequest"}, "propertyName": "decision"}, "oneOf": [{"$ref": "#/components/schemas/ApproveReviewRequest"}, {"$ref": "#/components/schemas/OverrideReviewRequest"}, {"$ref": "#/components/schemas/ReEvaluateReviewRequest"}], "title": "Payload"}}}, "required": true}, "responses": {"200": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReviewResponse"}}}, "description": "Scoring run reviewed and updated to completed or superseded status"}, "401": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Invalid or missing Bearer service token"}, "403": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Caller or reviewer not authorized"}, "404": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Scoring run not found for tenant"}, "409": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Idempotency conflict, stale run version, or unreviewable run state"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Validation error or invalid review decision payload"}, "503": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Re-evaluate admission is disabled by the operational kill switch"}}, "security": [{"HTTPBearer": []}], "summary": "Review a Scoring Run by Approve, Override, or Re-evaluate", "tags": ["Scoring Runs"]}}, "/v1/scoring-runs/{run_id}/trace": {"get": {"operationId": "get_scoring_run_trace_v1_scoring_runs__run_id__trace_get", "parameters": [{"description": "Scoring run ID", "in": "path", "name": "run_id", "required": true, "schema": {"description": "Scoring run ID", "maxLength": 36, "minLength": 1, "title": "Run Id", "type": "string"}}, {"description": "Tenant identifier for scoped tenant isolation query", "in": "header", "name": "X-Tenant-Id", "required": true, "schema": {"description": "Tenant identifier for scoped tenant isolation query", "maxLength": 255, "minLength": 1, "title": "X-Tenant-Id", "type": "string"}}], "responses": {"200": {"content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response Get Scoring Run Trace V1 Scoring Runs Run Id Trace Get", "type": "object"}}}, "description": "Internal execution trace for scoring run"}, "401": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Invalid or missing Bearer service token"}, "403": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Caller unauthorized or trace disabled in production"}, "404": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Scoring run or trace not found"}, "422": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}, "description": "Validation error for missing required headers"}}, "security": [{"HTTPBearer": []}], "summary": "Get internal execution trace for a scoring run (non-production only)", "tags": ["Scoring Runs"]}}}};
Redoc.init(spec, {
scrollYOffset: 50,
hideDownloadButton: false,
theme: {
colors: {
primary: {
main: '#1f93ff'
}
},
typography: {
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
headings: {
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
fontWeight: '700'
},
code: {
fontFamily: "'JetBrains Mono', monospace"
}
}
}
}, document.getElementById('redoc-container'));
</script>
</body>
</html>