{"openapi":"3.1.0","info":{"title":"Gift-CMS AI Agent — CMS (integration) (CMS)","description":"\nInternal AI agent for the Diplomatic Gift CMS — chat (sync + SSE stream),\nsession history, answer feedback, Genie-style insights, and admin surfaces\nfor RAG documents, schema curation, prompts, Text2SQL knowledge, and evals.\n\n### Conventions\n- **Envelope** — every JSON response is\n  `{\"statusCode\": int, \"status\": \"success\"|\"error\", \"error\": [str], \"data\": <payload>}`.\n  HTTP status always equals `statusCode` (Task 12 §14.4-§14.5). The canonical\n  validation status is **422**; business errors are **400/404/422/503**;\n  auth failures are **401/403**.\n- **Auth** — `Authorization: Bearer <JWT>` (HS256), realm-scoped per deployment:\n  required claims `sub` (UUID), `iss`, `aud` (scalar or single-element list),\n  `exp`, `actor_type` (`internal`|`supplier`), and at least one `roles` entry\n  after profile normalization (CMS: `QTHT`|`CB`|`LD`|`AI_ADMIN`; Portal adds\n  `SUPPLIER_ADMIN`|`SUPPLIER_MEMBER`; supplier actors require `organization_id`;\n  CMS accepts internal actors only). Agent endpoints need any agent role;\n  `/admin/*` needs `QTHT` or `AI_ADMIN` and an internal actor.\n  See docs/07-security-and-rbac.md and docs/15-api-integration-guide.md (Vietnamese).\n- **Pagination** — list endpoints take `page` & `page_size` and return\n  `data: {\"items\": [...], \"metadata\": {current_page, page_size, total_items}}`.\n- **Streaming** — `POST /api/v1/chat/stream` returns `text/event-stream`\n  frames: `meta` → (`step` + `tool`|`search`)* → `token`* → `done`\n  (full `AIResponse`). Direct answers skip `token` frames. Clients must\n  POST with headers (EventSource cannot), e.g. `fetch()` + `ReadableStream`.\n\n### Tools\n- **Test console** — `<base>/` (chat, SSE trace, feedback, admin panels).\n  Mounted only when `ENABLE_TEST_CONSOLE=true` **and** `APP_ENV=development`.\n- **ReDoc** — `<base>/api/redoc`.\n- Integration guide — `docs/15-api-integration-guide.md` (Vietnamese).\n\n\nThis OpenAPI document describes the isolated CMS deployment for source `ioc_gift_cms`.","version":"integration"},"servers":[{"url":"/","description":"CMS deployment"}],"paths":{"/api/v1/health":{"get":{"tags":["Health"],"summary":"Liveness — process check, no auth","description":"Process liveness; dependency outages must never make this endpoint fail.","operationId":"health_check_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Check Api V1 Health Get"}}}}}}},"/api/v1/health/ready":{"get":{"tags":["Health"],"summary":"Readiness — active-profile dependency checks, no auth","description":"Strict readiness without checking opposite-profile or supplier engines.","operationId":"health_ready_api_v1_health_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/capabilities":{"get":{"tags":["Capabilities"],"summary":"Get Capabilities","description":"Return active deployment metadata without endpoints, credentials, or secrets.","operationId":"get_capabilities_api_v1_capabilities_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse_Capabilities_"}}}}}}},"/api/v1/sessions":{"post":{"tags":["Sessions"],"summary":"Create a session","operationId":"create_session_api_v1_sessions_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse_SessionOut_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Sessions"],"summary":"List my sessions (paginated)","operationId":"list_sessions_api_v1_sessions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/sessions/{session_id}":{"get":{"tags":["Sessions"],"summary":"Session detail with messages","operationId":"get_session_api_v1_sessions__session_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse_SessionDetail_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Sessions"],"summary":"Rename / update metadata","operationId":"update_session_api_v1_sessions__session_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse_SessionOut_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Sessions"],"summary":"Soft-delete a session","operationId":"delete_session_api_v1_sessions__session_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat":{"post":{"tags":["Chat"],"summary":"UC-II.1 — Ask a question (one-shot)","description":"One agent turn: planner → tools (text2sql / RAG search) → synthesized answer, returned in a single response. Omit `session_id` to auto-create a session; pass it to continue an existing conversation.","operationId":"chat_api_v1_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}},"required":true},"responses":{"200":{"description":"Answer envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse_AIResponse_"},"examples":{"Success":{"summary":"Answer envelope with AIResponse payload","value":{"statusCode":200,"status":"success","error":[],"data":{"session_id":"42191e91-5bd4-4a5f-9c2f-1a4dc7bd0f21","message_id":"62cfd62f-0f4e-4d3f-8a91-2c6e0a9b41aa","answer":"Năm 2025 đã tặng cho Nhật Bản 2 món quà.","intent":"DATA","degraded":false,"sources":[{"type":"sql","ref":"text2sql (đã kiểm chứng)","snippet":"SELECT COUNT(*) ...","rows":[{"so_mon_qua":2}],"row_count":1,"truncated":false}],"references":[]}}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/chat/stream":{"post":{"tags":["Chat"],"summary":"UC-II.4 — Streamed answer (SSE)","description":"Same request body as `POST /chat`; responds `text/event-stream`.\n\nFrame order: `meta` `{session_id, message_id}` → per planner cycle a `step` frame followed by its `tool` or `search` observation → `token` `{text}` frames → `done` carrying the full `AIResponse`. Direct (chitchat) answers skip `token` frames. The sequence is linear and deterministic — see doc 08 §8.2 for the full contract.\n\nNote: this is a **POST with Authorization header** — `EventSource` cannot be used; read the stream with `fetch()` + `ReadableStream` (the test console at `/` does exactly this).","operationId":"chat_stream_api_v1_chat_stream_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/chat/messages/{message_id}/feedback":{"post":{"tags":["Chat"],"summary":"Rate an answer — Genie feedback loop","description":"`rating: 1` (up) or `-1` (down), optional `comment` (≤ 2000 chars). Only the session owner may rate assistant messages (foreign/unknown → 404, user messages → 400); owners may overwrite. Feeds `/admin/insights`.","operationId":"feedback_api_v1_chat_messages__message_id__feedback_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Message Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/chat/suggestions":{"get":{"tags":["Chat"],"summary":"Sample questions for the chat landing page","description":"Published `sample_question` knowledge assets visible to the caller's roles, priority-ordered — render as clickable chips that prefill the chat box.","operationId":"suggestions_api_v1_chat_suggestions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/documents":{"post":{"tags":["Admin"],"summary":"Upload a document (multipart) and ingest","operationId":"upload_document_api_v1_admin_documents_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_document_api_v1_admin_documents_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Admin"],"summary":"List documents (paginated, filter by status)","operationId":"list_documents_api_v1_admin_documents_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/documents/{doc_id}":{"get":{"tags":["Admin"],"summary":"Get one document (metadata + ingest state)","operationId":"get_document_api_v1_admin_documents__doc_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Admin"],"summary":"Update document metadata; vector payloads synced in place","operationId":"update_document_metadata_api_v1_admin_documents__doc_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Doc Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentMetadataUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a document + its vectors","operationId":"delete_document_api_v1_admin_documents__doc_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/documents/{doc_id}/reindex":{"post":{"tags":["Admin"],"summary":"Re-parse and re-embed a document","operationId":"reindex_document_api_v1_admin_documents__doc_id__reindex_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/schema":{"get":{"tags":["Admin"],"summary":"List schema descriptions (filter by table_name)","operationId":"list_schema_api_v1_admin_schema_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"table_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Table Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/schema/{table_name}/{column_name}":{"put":{"tags":["Admin"],"summary":"Update description_vi / allowed_roles (query params)","operationId":"update_schema_row_api_v1_admin_schema__table_name___column_name__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"table_name","in":"path","required":true,"schema":{"type":"string","title":"Table Name"}},{"name":"column_name","in":"path","required":true,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Column Name"}},{"name":"description_vi","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Vi"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"title":"Allowed Roles"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/schema/reflect":{"post":{"tags":["Admin"],"summary":"Reflect information_schema → skeleton rows","description":"Reflection job v2 (admin-triggered): skeleton rows from information_schema.","operationId":"reflect_schema_api_v1_admin_schema_reflect_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/prompts":{"get":{"tags":["Admin"],"summary":"List prompt templates (name, version, active)","operationId":"list_prompts_api_v1_admin_prompts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/prompts/{name}":{"get":{"tags":["Admin"],"summary":"Get active prompt template by name and language","operationId":"get_prompt_api_v1_admin_prompts__name__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"vi","title":"Language"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Admin"],"summary":"Save a new active version (template via query param)","operationId":"update_prompt_api_v1_admin_prompts__name__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"template","in":"query","required":true,"schema":{"type":"string","title":"Template"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"vi","title":"Language"}},{"name":"note","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/audit/messages":{"get":{"tags":["Admin"],"summary":"Search assistant messages (intent/degraded/date)","operationId":"audit_messages_api_v1_admin_audit_messages_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"intent","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent"}},{"name":"degraded","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Degraded"}},{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/audit/messages/{message_id}/trace":{"get":{"tags":["Admin"],"summary":"Per-node trace for one message","description":"Per-node trace lookup; out-of-profile messages yield 404, not traces.","operationId":"audit_trace_api_v1_admin_audit_messages__message_id__trace_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Message Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/insights":{"get":{"tags":["Admin"],"summary":"Quality aggregates — Genie Monitor equivalent","description":"Feedback/degradation aggregates over assistant answers in a time window.\n\nGenie's Monitor tab equivalent: what was asked, how often answers degrade,\nand which answers users rated down — the curation loop's work list.","operationId":"insights_api_v1_admin_insights_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":14,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/text2sql/knowledge":{"get":{"tags":["Admin"],"summary":"List knowledge assets (paginated, filter by status)","operationId":"list_text2sql_knowledge_api_v1_admin_text2sql_knowledge_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":20,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Admin"],"summary":"Create a draft asset (typed payload per kind)","operationId":"create_text2sql_knowledge_draft_api_v1_admin_text2sql_knowledge_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeAssetCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/text2sql/knowledge/{asset_key}":{"get":{"tags":["Admin"],"summary":"Revision history of one asset (oldest version first)","operationId":"get_text2sql_knowledge_revisions_api_v1_admin_text2sql_knowledge__asset_key__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_key","in":"path","required":true,"schema":{"type":"string","title":"Asset Key"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Admin"],"summary":"Create a new draft version for an asset","operationId":"new_text2sql_knowledge_draft_version_api_v1_admin_text2sql_knowledge__asset_key__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_key","in":"path","required":true,"schema":{"type":"string","title":"Asset Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeAssetUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/text2sql/knowledge/{asset_key}/{version}/validate":{"post":{"tags":["Admin"],"summary":"Validate a revision (guards + EXPLAIN for sql_example)","operationId":"validate_text2sql_knowledge_api_v1_admin_text2sql_knowledge__asset_key___version__validate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_key","in":"path","required":true,"schema":{"type":"string","title":"Asset Key"}},{"name":"version","in":"path","required":true,"schema":{"type":"integer","title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/text2sql/knowledge/{asset_key}/{version}/publish":{"post":{"tags":["Admin"],"summary":"Validate + publish; retires the prior active version","operationId":"publish_text2sql_knowledge_api_v1_admin_text2sql_knowledge__asset_key___version__publish_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_key","in":"path","required":true,"schema":{"type":"string","title":"Asset Key"}},{"name":"version","in":"path","required":true,"schema":{"type":"integer","title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/text2sql/knowledge/{asset_key}/{version}/retire":{"post":{"tags":["Admin"],"summary":"Retire a revision and remove it from retrieval","operationId":"retire_text2sql_knowledge_api_v1_admin_text2sql_knowledge__asset_key___version__retire_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_key","in":"path","required":true,"schema":{"type":"string","title":"Asset Key"}},{"name":"version","in":"path","required":true,"schema":{"type":"integer","title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/text2sql/knowledge/reindex":{"post":{"tags":["Admin"],"summary":"Rebuild all schema + knowledge vector points","operationId":"reindex_text2sql_knowledge_api_v1_admin_text2sql_knowledge_reindex_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/eval/retrieval":{"post":{"tags":["Evaluation"],"summary":"RAG retrieval eval — recall/precision@K over an inline item set","description":"Runs the retriever over the given set and reports recall/precision@K.\n\nThe held-out set is supplied inline for v1 (a persisted eval-set table can\nreplace it without changing this contract).","operationId":"retrieval_eval_api_v1_admin_eval_retrieval_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/eval/text2sql/runs":{"get":{"tags":["Evaluation"],"summary":"List persisted Text2SQL eval runs for the active source (newest first)","operationId":"list_text2sql_runs_api_v1_admin_eval_text2sql_runs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/eval/text2sql/runs/{run_id}":{"get":{"tags":["Evaluation"],"summary":"Persisted Text2SQL eval run detail with every case result","operationId":"get_text2sql_run_api_v1_admin_eval_text2sql_runs__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/eval/text2sql/cases":{"get":{"tags":["Evaluation"],"summary":"List Text2SQL acceptance cases","operationId":"list_text2sql_cases_api_v1_admin_eval_text2sql_cases_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/eval/text2sql/run":{"post":{"tags":["Evaluation"],"summary":"Run Text2SQL acceptance suite (filter by tags/case_keys) and persist the run","description":"Run eval cases through the real facade (read-only engines, fixed eval user).","operationId":"run_text2sql_eval_api_v1_admin_eval_text2sql_run_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Text2SQLRunRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"AIResponse":{"properties":{"session_id":{"type":"string","format":"uuid","title":"Session Id"},"message_id":{"type":"string","format":"uuid","title":"Message Id"},"answer":{"type":"string","title":"Answer"},"intent":{"type":"string","enum":["DATA","DOC","CHAT","DATA+DOC"],"title":"Intent"},"degraded":{"type":"boolean","title":"Degraded","default":false},"sources":{"items":{"$ref":"#/components/schemas/SourceRef"},"type":"array","title":"Sources","default":[]},"references":{"items":{"type":"string"},"type":"array","title":"References","default":[]}},"type":"object","required":["session_id","message_id","answer","intent"],"title":"AIResponse"},"Body_upload_document_api_v1_admin_documents_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"title":{"type":"string","title":"Title"},"doc_type":{"type":"string","title":"Doc Type","default":"pdf"},"classification":{"type":"string","title":"Classification","default":"internal"},"scope":{"type":"string","title":"Scope","default":"global"},"organization_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Id"},"allowed_actor_types":{"type":"string","title":"Allowed Actor Types","default":"internal"},"allowed_role_keys":{"type":"string","title":"Allowed Role Keys","default":"QTHT,CB,LD"}},"type":"object","required":["file","title"],"title":"Body_upload_document_api_v1_admin_documents_post"},"Capabilities":{"properties":{"profile":{"type":"string","title":"Profile"},"source_id":{"type":"string","title":"Source Id"},"actor_modes":{"items":{"type":"string"},"type":"array","title":"Actor Modes"},"enabled_features":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Enabled Features"}},"type":"object","required":["profile","source_id","actor_modes","enabled_features"],"title":"Capabilities","description":"Features and actor modes available in this isolated deployment."},"ChatRequest":{"properties":{"session_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Session Id"},"question":{"type":"string","maxLength":10000,"minLength":1,"title":"Question"}},"type":"object","required":["question"],"title":"ChatRequest"},"DataResponse":{"properties":{"statusCode":{"type":"integer","title":"Statuscode","default":200},"status":{"type":"string","title":"Status","default":"success"},"error":{"items":{"type":"string"},"type":"array","title":"Error","default":[]},"data":{"anyOf":[{},{"type":"null"}],"title":"Data"}},"type":"object","title":"DataResponse"},"DataResponse_AIResponse_":{"properties":{"statusCode":{"type":"integer","title":"Statuscode","default":200},"status":{"type":"string","title":"Status","default":"success"},"error":{"items":{"type":"string"},"type":"array","title":"Error","default":[]},"data":{"anyOf":[{"$ref":"#/components/schemas/AIResponse"},{"type":"null"}]}},"type":"object","title":"DataResponse[AIResponse]"},"DataResponse_Capabilities_":{"properties":{"statusCode":{"type":"integer","title":"Statuscode","default":200},"status":{"type":"string","title":"Status","default":"success"},"error":{"items":{"type":"string"},"type":"array","title":"Error","default":[]},"data":{"anyOf":[{"$ref":"#/components/schemas/Capabilities"},{"type":"null"}]}},"type":"object","title":"DataResponse[Capabilities]"},"DataResponse_SessionDetail_":{"properties":{"statusCode":{"type":"integer","title":"Statuscode","default":200},"status":{"type":"string","title":"Status","default":"success"},"error":{"items":{"type":"string"},"type":"array","title":"Error","default":[]},"data":{"anyOf":[{"$ref":"#/components/schemas/SessionDetail"},{"type":"null"}]}},"type":"object","title":"DataResponse[SessionDetail]"},"DataResponse_SessionOut_":{"properties":{"statusCode":{"type":"integer","title":"Statuscode","default":200},"status":{"type":"string","title":"Status","default":"success"},"error":{"items":{"type":"string"},"type":"array","title":"Error","default":[]},"data":{"anyOf":[{"$ref":"#/components/schemas/SessionOut"},{"type":"null"}]}},"type":"object","title":"DataResponse[SessionOut]"},"DocumentMetadataUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Title"},"classification":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Classification"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"},"organization_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Id"},"allowed_actor_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Actor Types"},"allowed_role_keys":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Role Keys"}},"type":"object","title":"DocumentMetadataUpdate","description":"Editable metadata; omitted fields keep their current values.\n\n``doc_type``/file content are immutable — change those via delete +\nre-upload (or ``/reindex`` after replacing the stored file)."},"EvalItem":{"properties":{"question":{"type":"string","title":"Question"},"expected_doc_ids":{"items":{"type":"string"},"type":"array","title":"Expected Doc Ids"}},"type":"object","required":["question","expected_doc_ids"],"title":"EvalItem"},"EvalRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EvalItem"},"type":"array","title":"Items"},"top_k":{"type":"integer","title":"Top K","default":5}},"type":"object","required":["items"],"title":"EvalRequest"},"FeedbackRequest":{"properties":{"rating":{"type":"integer","enum":[1,-1],"title":"Rating"},"comment":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Comment"}},"type":"object","required":["rating"],"title":"FeedbackRequest","description":"Owner-submitted answer rating (Genie-style feedback loop, doc 14)."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"KnowledgeAssetCreate":{"properties":{"asset_key":{"type":"string","maxLength":128,"minLength":1,"title":"Asset Key"},"kind":{"type":"string","enum":["instruction","sql_example","measure","filter","sample_question"],"title":"Kind"},"title":{"type":"string","maxLength":255,"minLength":1,"title":"Title"},"table_names":{"items":{"type":"string"},"type":"array","title":"Table Names"},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases"},"allowed_roles":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Allowed Roles"},"priority":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Priority","default":50},"payload":{"additionalProperties":true,"type":"object","title":"Payload"}},"type":"object","required":["asset_key","kind","title","allowed_roles","payload"],"title":"KnowledgeAssetCreate"},"KnowledgeAssetUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"table_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Table Names"},"aliases":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Aliases"},"allowed_roles":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Roles"},"priority":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Priority"},"payload":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Payload"}},"type":"object","title":"KnowledgeAssetUpdate","description":"Fields a new draft version may change; published revisions are immutable."},"MessageOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent"},"degraded":{"type":"boolean","title":"Degraded","default":false},"sources":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Sources"},"references":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"References"},"feedback_rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Feedback Rating"},"feedback_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Comment"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","role","content","created_at"],"title":"MessageOut"},"SessionCreate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","default":"Cuộc trò chuyện mới"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"}},"type":"object","title":"SessionCreate"},"SessionDetail":{"properties":{"session":{"$ref":"#/components/schemas/SessionOut"},"messages":{"items":{"$ref":"#/components/schemas/MessageOut"},"type":"array","title":"Messages"}},"type":"object","required":["session","messages"],"title":"SessionDetail"},"SessionOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"user_id":{"type":"string","title":"User Id"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","title","user_id","created_at"],"title":"SessionOut"},"SessionUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"metadata_json":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata Json"}},"type":"object","title":"SessionUpdate"},"SourceRef":{"properties":{"type":{"type":"string","enum":["sql","document"],"title":"Type"},"ref":{"type":"string","title":"Ref"},"snippet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snippet"},"rows":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Rows"},"row_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Row Count"},"truncated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Truncated"},"statements":{"anyOf":[{"items":{"$ref":"#/components/schemas/StatementSlice"},"type":"array"},{"type":"null"}],"title":"Statements"}},"type":"object","required":["type","ref"],"title":"SourceRef"},"StatementSlice":{"properties":{"label":{"type":"string","title":"Label","default":""},"rows":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Rows","default":[]},"row_count":{"type":"integer","title":"Row Count","default":0},"truncated":{"type":"boolean","title":"Truncated","default":false}},"type":"object","title":"StatementSlice","description":"Display slice of one statement in a structured multi-SELECT answer."},"Text2SQLRunRequest":{"properties":{"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"case_keys":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Case Keys"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","title":"Text2SQLRunRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"Health","description":"Liveness & readiness (no auth) — for monitoring and wiring checks."},{"name":"Chat","description":"Ask questions (sync or SSE stream), rate answers, get sample-question suggestions."},{"name":"Sessions","description":"Conversation CRUD + message history, scoped to the caller."},{"name":"Admin","description":"RAG documents, schema curation, prompt versions, audit/insights, Text2SQL knowledge lifecycle. Roles: QTHT | AI_ADMIN."},{"name":"Evaluation","description":"RAG retrieval + Text2SQL acceptance suites. Roles: QTHT | AI_ADMIN."}]}