{ "openapi": "3.1.0", "info": { "title": "fca-api", "version": "0.0.1" }, "paths": { "/": { "get": { "summary": "Root", "operationId": "root__get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } } } } }, "/api/v1/auth/register": { "post": { "tags": ["v1", "auth", "auth", "user"], "summary": "Register", "description": "Register a new user (student or lecturer). Source: openapi-spec /auth/register", "operationId": "register_api_v1_auth_register_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterRequest" } } }, "required": true }, "responses": { "201": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/login": { "post": { "tags": ["v1", "auth"], "summary": "Login", "description": "Login with email + password and receive a JWT. Source: openapi-spec /auth/login", "operationId": "login_api_v1_auth_login_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/activate/{token}": { "get": { "tags": ["v1", "auth"], "summary": "Activate Account", "description": "Activate an account from an email verification link.", "operationId": "activate_account_api_v1_auth_activate__token__get", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Token" }, "name": "token", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActivateAccountResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/login/api-key": { "post": { "tags": ["v1", "auth"], "summary": "Login With Api Key", "description": "Exchange an API key for a JWT. Source: openapi-spec /auth/login/api-key", "operationId": "login_with_api_key_api_v1_auth_login_api_key_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyLoginRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LoginResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/documents/upload": { "post": { "tags": ["v1", "documents"], "summary": "Upload course material document", "description": "Upload a file to be used as a knowledge base. Supported formats: PDF, PPT, PPTX, TXT, XLS, XLSX. Maximum size: 100 MB. Asynchronous — use the status endpoint to check progress.", "operationId": "upload_document_api_v1_documents_upload_post", "requestBody": { "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/Body_upload_document_api_v1_documents_upload_post" } } }, "required": true }, "responses": { "202": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UploadDocumentResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/courses/{course_id}/documents": { "get": { "tags": ["v1", "documents"], "summary": "List documents per course", "description": "Get all knowledge base documents for a specific course.", "operationId": "list_documents_by_course_api_v1_courses__course_id__documents_get", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Course Id" }, "name": "course_id", "in": "path" }, { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Page", "default": 1 }, "name": "page", "in": "query" }, { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Limit", "default": 10 }, "name": "limit", "in": "query" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentListResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/courses/{course_id}/documents/{document_id}": { "delete": { "tags": ["v1", "documents"], "summary": "Delete course document", "description": "Delete a document from a course, including its vector embeddings and storage file.", "operationId": "delete_document_api_v1_courses__course_id__documents__document_id__delete", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Course Id" }, "name": "course_id", "in": "path" }, { "required": true, "schema": { "type": "string", "title": "Document Id" }, "name": "document_id", "in": "path" } ], "responses": { "204": { "description": "Successful Response" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/courses": { "get": { "tags": ["v1", "courses"], "summary": "List courses", "operationId": "get_courses_api_v1_courses_get", "parameters": [ { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Page", "default": 1 }, "name": "page", "in": "query" }, { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Limit", "default": 10 }, "name": "limit", "in": "query" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseListResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "post": { "tags": ["v1", "courses"], "summary": "Create course", "operationId": "create_course_api_v1_courses_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCourseRequest" } } }, "required": true }, "responses": { "201": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/courses/{course_id}": { "get": { "tags": ["v1", "courses"], "summary": "Get course detail", "operationId": "get_course_api_v1_courses__course_id__get", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "Course Id" }, "name": "course_id", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "put": { "tags": ["v1", "courses"], "summary": "Update course", "operationId": "update_course_api_v1_courses__course_id__put", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "Course Id" }, "name": "course_id", "in": "path" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCourseRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "delete": { "tags": ["v1", "courses"], "summary": "Delete course", "operationId": "delete_course_api_v1_courses__course_id__delete", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "Course Id" }, "name": "course_id", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/user": { "get": { "tags": ["v1", "user"], "summary": "Get User List", "operationId": "get_user_list_api_v1_user_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FindUserResult" } } } } }, "security": [ { "JWTBearer": [] }, { "JWTBearer": [] } ] } }, "/api/v1/user/{user_id}": { "get": { "tags": ["v1", "user"], "summary": "Get User", "operationId": "get_user_api_v1_user__user_id__get", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "User Id" }, "name": "user_id", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] }, { "JWTBearer": [] } ] }, "delete": { "tags": ["v1", "user"], "summary": "Delete User", "operationId": "delete_user_api_v1_user__user_id__delete", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "User Id" }, "name": "user_id", "in": "path" } ], "responses": { "204": { "description": "Successful Response" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] }, { "JWTBearer": [] } ] }, "patch": { "tags": ["v1", "user"], "summary": "Update User", "operationId": "update_user_api_v1_user__user_id__patch", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "User Id" }, "name": "user_id", "in": "path" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PatchUser" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] }, { "JWTBearer": [] } ] } }, "/api/v1/chats/sessions": { "get": { "tags": ["v1", "Chat"], "summary": "Get Chat Sessions", "description": "List chat sessions with pagination.", "operationId": "get_chat_sessions_api_v1_chats_sessions_get", "parameters": [ { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Page", "default": 1 }, "name": "page", "in": "query" }, { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Limit", "default": 10 }, "name": "limit", "in": "query" }, { "required": false, "schema": { "type": "string", "title": "Course Id" }, "name": "course_id", "in": "query" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatSessionListResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "post": { "tags": ["v1", "Chat"], "summary": "Create Chat Session", "description": "Create a new chat session.", "operationId": "create_chat_session_api_v1_chats_sessions_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateChatSessionRequest" } } }, "required": true }, "responses": { "201": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatSessionResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/chats/sessions/{session_id}": { "get": { "tags": ["v1", "Chat"], "summary": "Get Chat Session", "description": "Get chat session details.", "operationId": "get_chat_session_api_v1_chats_sessions__session_id__get", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Session Id" }, "name": "session_id", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatSessionResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "delete": { "tags": ["v1", "Chat"], "summary": "Delete Chat Session", "description": "Delete a chat session.", "operationId": "delete_chat_session_api_v1_chats_sessions__session_id__delete", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Session Id" }, "name": "session_id", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/chats/sessions/{session_id}/messages": { "get": { "tags": ["v1", "Chat"], "summary": "Get Chat History", "description": "Get all messages in a session.", "operationId": "get_chat_history_api_v1_chats_sessions__session_id__messages_get", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Session Id" }, "name": "session_id", "in": "path" }, { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Page", "default": 1 }, "name": "page", "in": "query" }, { "required": false, "schema": { "type": "integer", "minimum": 1.0, "title": "Limit", "default": 20 }, "name": "limit", "in": "query" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatHistoryResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "post": { "tags": ["v1", "Chat"], "summary": "Send Message Rest", "description": "Send a message to AI via REST fallback.", "operationId": "send_message_rest_api_v1_chats_sessions__session_id__messages_post", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Session Id" }, "name": "session_id", "in": "path" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatRESTRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatMessageResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/chats/sessions/{session_id}/stream": { "post": { "tags": ["v1", "Chat"], "summary": "Stream message (SSE)", "description": "Send a message to AI and stream the response via Server-Sent Events (SSE).", "operationId": "send_message_stream_sse_api_v1_chats_sessions__session_id__stream_post", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Session Id" }, "name": "session_id", "in": "path" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatRESTRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config": { "get": { "tags": ["v1", "admin"], "summary": "Get full RAG config", "description": "Returns the current LLM, VectorDB, and Retrieval configuration from the database.", "operationId": "get_full_config_api_v1_admin_rag_config_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RAGConfigResponse" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/llm": { "get": { "tags": ["v1", "admin"], "summary": "Get LLM config", "description": "Returns the current LLM configuration (model, temperature, max_tokens, request_timeout).", "operationId": "get_llm_config_api_v1_admin_rag_config_llm_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LLMConfigResponse" } } } } }, "security": [ { "JWTBearer": [] } ] }, "patch": { "tags": ["v1", "admin"], "summary": "Update LLM config", "description": "Partially update the LLM configuration. Only provided fields will be changed.", "operationId": "update_llm_config_api_v1_admin_rag_config_llm_patch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LLMConfigPayload" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LLMConfigResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/llm/options": { "get": { "tags": ["v1", "admin"], "summary": "Get LLM provider options", "description": "Returns a tree-like mapping of available LLM providers and their corresponding models and base URLs for frontend dropdowns.", "operationId": "get_llm_provider_options_api_v1_admin_rag_config_llm_options_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "object", "title": "Response Get Llm Provider Options Api V1 Admin Rag Config Llm Options Get" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/llm/active": { "patch": { "tags": ["v1", "admin"], "summary": "Set active LLM model", "description": "Explicitly set the active provider and model for the RAG pipeline.", "operationId": "set_active_llm_model_api_v1_admin_rag_config_llm_active_patch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActiveLLMModelPayload" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LLMConfigResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/vector_db": { "get": { "tags": ["v1", "admin"], "summary": "Get VectorDB config", "description": "Returns the current VectorDB configuration (embedding model, chunk settings, persist path).", "operationId": "get_vector_db_config_api_v1_admin_rag_config_vector_db_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorDBConfigResponse" } } } } }, "security": [ { "JWTBearer": [] } ] }, "patch": { "tags": ["v1", "admin"], "summary": "Update VectorDB config", "description": "Partially update the VectorDB configuration. persist_path is read-only.", "operationId": "update_vector_db_config_api_v1_admin_rag_config_vector_db_patch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorDBConfigPayload" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorDBConfigResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/vector_db/options": { "get": { "tags": ["v1", "admin"], "summary": "Get Vector DB options", "description": "Returns available embedding models for frontend dropdowns.", "operationId": "get_vector_db_options_api_v1_admin_rag_config_vector_db_options_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "object", "title": "Response Get Vector Db Options Api V1 Admin Rag Config Vector Db Options Get" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/retrieval": { "get": { "tags": ["v1", "admin"], "summary": "Get Retrieval config", "description": "Returns the current Retrieval configuration (top_k, weights, reranker, thresholds).", "operationId": "get_retrieval_config_api_v1_admin_rag_config_retrieval_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RetrievalConfigResponse" } } } } }, "security": [ { "JWTBearer": [] } ] }, "patch": { "tags": ["v1", "admin"], "summary": "Update Retrieval config", "description": "Partially update retrieval configuration. Only provided fields will be changed.", "operationId": "update_retrieval_config_api_v1_admin_rag_config_retrieval_patch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RetrievalConfigPayload" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RetrievalConfigResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/admin/rag/config/retrieval/options": { "get": { "tags": ["v1", "admin"], "summary": "Get Retrieval options", "description": "Returns available reranker models for frontend dropdowns.", "operationId": "get_retrieval_options_api_v1_admin_rag_config_retrieval_options_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "object", "title": "Response Get Retrieval Options Api V1 Admin Rag Config Retrieval Options Get" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/auth/api-key/generate": { "post": { "tags": ["v1", "auth-iframe"], "summary": "Generate Api Key", "description": "Generate API key for Iframe SSO.\nValidates source domain against whitelist.\n\nUser data fields (email, username, phone, name, identity_number) are passed\nbut only email, username, and name are stored in the User table.", "operationId": "generate_api_key_api_v1_auth_api_key_generate_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenerateAPIKeyRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GenerateAPIKeyResponse" } } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/api-key/verify": { "post": { "tags": ["v1", "auth-iframe"], "summary": "Verify Api Key And Login", "description": "Verify API key and create JWT token for Iframe.\nStores token in secure HTTP-only cookie.", "operationId": "verify_api_key_and_login_api_v1_auth_api_key_verify_post", "parameters": [ { "required": true, "schema": { "type": "string", "title": "Api Key" }, "name": "api_key", "in": "query" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/api/v1/auth/iframe/status": { "get": { "tags": ["v1", "auth-iframe"], "summary": "Check Iframe Login Status", "description": "Check if user is already logged in via Iframe.\nReturns user info if logged in.", "operationId": "check_iframe_login_status_api_v1_auth_iframe_status_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/auth/whitelist": { "get": { "tags": ["v1", "auth-iframe"], "summary": "Get Whitelist", "description": "List all whitelist entries (Admin only)", "operationId": "get_whitelist_api_v1_auth_whitelist_get", "parameters": [ { "required": false, "schema": { "type": "integer", "title": "Page", "default": 1 }, "name": "page", "in": "query" }, { "required": false, "schema": { "type": "integer", "title": "Page Size", "default": 100 }, "name": "page_size", "in": "query" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "post": { "tags": ["v1", "auth-iframe"], "summary": "Add Whitelist", "description": "Add new domain to whitelist (Admin only)", "operationId": "add_whitelist_api_v1_auth_whitelist_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpsertWhitelist" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } }, "/api/v1/auth/whitelist/{whitelist_id}": { "delete": { "tags": ["v1", "auth-iframe"], "summary": "Delete Whitelist", "description": "Delete whitelist entry (Admin only)", "operationId": "delete_whitelist_api_v1_auth_whitelist__whitelist_id__delete", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "Whitelist Id" }, "name": "whitelist_id", "in": "path" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] }, "patch": { "tags": ["v1", "auth-iframe"], "summary": "Update Whitelist", "description": "Update whitelist entry (Admin only)", "operationId": "update_whitelist_api_v1_auth_whitelist__whitelist_id__patch", "parameters": [ { "required": true, "schema": { "type": "integer", "title": "Whitelist Id" }, "name": "whitelist_id", "in": "path" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpsertWhitelist" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } }, "security": [ { "JWTBearer": [] } ] } } }, "components": { "schemas": { "ActivateAccountResponse": { "properties": { "message": { "type": "string", "title": "Message" }, "user": { "$ref": "#/components/schemas/UserResponse" } }, "type": "object", "required": ["message", "user"], "title": "ActivateAccountResponse" }, "ActiveLLMModelPayload": { "properties": { "active_provider": { "type": "string", "minLength": 1, "title": "Active Provider", "description": "Provider name (e.g., openai, deepseek)" }, "active_model": { "type": "string", "minLength": 1, "title": "Active Model", "description": "Model name to be activated" } }, "type": "object", "required": ["active_provider", "active_model"], "title": "ActiveLLMModelPayload" }, "ApiKeyLoginRequest": { "properties": { "api_key": { "type": "string", "title": "Api Key" } }, "type": "object", "required": ["api_key"], "title": "ApiKeyLoginRequest", "description": "POST /auth/login/api-key — body." }, "Body_upload_document_api_v1_documents_upload_post": { "properties": { "file": { "type": "string", "format": "binary", "title": "File", "description": "Course material file" }, "course_id": { "type": "string", "title": "Course Id", "description": "Target course UUID" } }, "type": "object", "required": ["file", "course_id"], "title": "Body_upload_document_api_v1_documents_upload_post" }, "ChatHistoryResponse": { "properties": { "data": { "items": { "$ref": "#/components/schemas/ChatMessageResponse" }, "type": "array", "title": "Data" } }, "type": "object", "required": ["data"], "title": "ChatHistoryResponse", "description": "Response format for GET /sessions/{session_id}/messages." }, "ChatMessageResponse": { "properties": { "uuid_id": { "type": "string", "title": "Uuid Id", "description": "Public UUID of the message" }, "role": { "type": "string", "title": "Role" }, "content": { "type": "string", "title": "Content" }, "sources": { "items": { "$ref": "#/components/schemas/DocumentSourceDTO" }, "type": "array", "title": "Sources", "default": [] }, "created_at": { "type": "string", "format": "date-time", "title": "Created At" } }, "type": "object", "required": ["uuid_id", "role", "content", "created_at"], "title": "ChatMessageResponse", "description": "Mirrors the message object in OpenAPI spec." }, "ChatRESTRequest": { "properties": { "content": { "type": "string", "title": "Content", "description": "The user\u0027s prompt text." } }, "type": "object", "required": ["content"], "title": "ChatRESTRequest", "description": "Payload for the REST fallback endpoint sending a message to a session." }, "ChatSessionListResponse": { "properties": { "data": { "items": { "$ref": "#/components/schemas/ChatSessionResponse" }, "type": "array", "title": "Data" }, "pagination": { "$ref": "#/components/schemas/PaginationDTO" } }, "type": "object", "required": ["data", "pagination"], "title": "ChatSessionListResponse" }, "ChatSessionResponse": { "properties": { "uuid_id": { "type": "string", "title": "Uuid Id", "description": "Public UUID of the session." }, "user_id": { "type": "string", "title": "User Id", "description": "User\u0027s public UUID (mocked or stringified internally if missing)." }, "user_name": { "type": "string", "title": "User Name" }, "course_id": { "type": "string", "title": "Course Id" }, "course_name": { "type": "string", "title": "Course Name" }, "title": { "type": "string", "title": "Title" }, "message_count": { "type": "integer", "title": "Message Count" }, "last_message_at": { "type": "string", "format": "date-time", "title": "Last Message At" }, "created_at": { "type": "string", "format": "date-time", "title": "Created At" }, "updated_at": { "type": "string", "format": "date-time", "title": "Updated At" } }, "type": "object", "required": [ "uuid_id", "user_id", "course_id", "title", "message_count", "created_at", "updated_at" ], "title": "ChatSessionResponse", "description": "Mirrors the ChatSession schema in OpenAPI spec." }, "CourseListResponse": { "properties": { "data": { "items": { "$ref": "#/components/schemas/CourseResponse" }, "type": "array", "title": "Data" }, "total": { "type": "integer", "title": "Total" }, "page": { "type": "integer", "title": "Page" }, "limit": { "type": "integer", "title": "Limit" } }, "type": "object", "required": ["data", "total", "page", "limit"], "title": "CourseListResponse" }, "CourseResponse": { "properties": { "id": { "type": "integer", "title": "Id" }, "title": { "type": "string", "title": "Title" }, "description": { "type": "string", "title": "Description" }, "created_by": { "type": "integer", "title": "Created By" } }, "type": "object", "required": ["id", "title"], "title": "CourseResponse" }, "CreateChatSessionRequest": { "properties": { "course_id": { "type": "string", "title": "Course Id", "description": "UUID of the course" }, "title": { "type": "string", "title": "Title", "description": "Session title" } }, "type": "object", "required": ["course_id", "title"], "title": "CreateChatSessionRequest" }, "CreateCourseRequest": { "properties": { "title": { "type": "string", "title": "Title" }, "description": { "type": "string", "title": "Description" } }, "type": "object", "required": ["title"], "title": "CreateCourseRequest" }, "DocumentListResponse": { "properties": { "data": { "items": { "$ref": "#/components/schemas/DocumentResponse" }, "type": "array", "title": "Data" }, "pagination": { "$ref": "#/components/schemas/PaginationDTO" } }, "type": "object", "required": ["data", "pagination"], "title": "DocumentListResponse", "description": "GET /courses/{course_id}/documents — 200 response wrapper." }, "DocumentResponse": { "properties": { "id": { "type": "string", "title": "Id" }, "filename": { "type": "string", "title": "Filename" }, "file_type": { "$ref": "#/components/schemas/FileType" }, "file_size": { "type": "integer", "title": "File Size" }, "status": { "$ref": "#/components/schemas/DocumentStatus" }, "course_id": { "type": "string", "title": "Course Id" }, "course_name": { "type": "string", "title": "Course Name" }, "uploaded_by": { "type": "string", "title": "Uploaded By" }, "uploader_name": { "type": "string", "title": "Uploader Name" }, "summary": { "type": "string", "title": "Summary" }, "chunk_count": { "type": "integer", "title": "Chunk Count" }, "error": { "type": "string", "title": "Error" }, "created_at": { "type": "string", "format": "date-time", "title": "Created At" }, "updated_at": { "type": "string", "format": "date-time", "title": "Updated At" } }, "type": "object", "required": [ "id", "filename", "file_type", "file_size", "status", "course_id", "uploaded_by", "created_at", "updated_at" ], "title": "DocumentResponse", "description": "Mirrors the OpenAPI `Document` schema exactly (snake_case, all fields).\nConsumers should use `from_document()` to build from a DB record." }, "DocumentSourceDTO": { "properties": { "document_id": { "type": "string", "title": "Document Id" }, "filename": { "type": "string", "title": "Filename" }, "excerpt": { "type": "string", "title": "Excerpt" } }, "type": "object", "required": ["document_id", "filename", "excerpt"], "title": "DocumentSourceDTO" }, "DocumentStatus": { "type": "string", "enum": ["processing", "ready", "failed"], "title": "DocumentStatus", "description": "An enumeration." }, "FileType": { "type": "string", "enum": ["pdf", "ppt", "pptx", "txt", "xls", "xlsx"], "title": "FileType", "description": "An enumeration." }, "FindUserResult": { "properties": { "founds": { "items": { "$ref": "#/components/schemas/User" }, "type": "array", "title": "Founds" }, "search_options": { "$ref": "#/components/schemas/SearchOptions" } }, "type": "object", "title": "FindUserResult" }, "GenerateAPIKeyRequest": { "properties": { "email": { "type": "string", "title": "Email" }, "username": { "type": "string", "title": "Username" }, "phone": { "type": "string", "title": "Phone" }, "name": { "type": "string", "title": "Name" }, "identity_number": { "type": "string", "title": "Identity Number" }, "source_domain": { "type": "string", "title": "Source Domain" }, "role": { "$ref": "#/components/schemas/app__schema__auth_schema__Role" } }, "type": "object", "required": [ "email", "username", "phone", "name", "identity_number", "source_domain", "role" ], "title": "GenerateAPIKeyRequest" }, "GenerateAPIKeyResponse": { "properties": { "api_key": { "type": "string", "title": "Api Key" }, "message": { "type": "string", "title": "Message" } }, "type": "object", "required": ["api_key", "message"], "title": "GenerateAPIKeyResponse" }, "HTTPValidationError": { "properties": { "detail": { "items": { "$ref": "#/components/schemas/ValidationError" }, "type": "array", "title": "Detail" } }, "type": "object", "title": "HTTPValidationError" }, "LLMConfigPayload": { "properties": { "active_provider": { "type": "string", "title": "Active Provider" }, "active_model": { "type": "string", "title": "Active Model" }, "providers": { "additionalProperties": { "$ref": "#/components/schemas/ProviderInfoPayload" }, "type": "object", "title": "Providers" }, "api_key": { "type": "string", "minLength": 1, "title": "Api Key", "description": "Environment variable name or API key." }, "reasoning_effort": { "type": "string", "title": "Reasoning Effort", "description": "Provider/model-specific reasoning effort. OpenAI reasoning models use values such as none, minimal, low, medium, high, or xhigh depending on the model. DeepSeek thinking mode uses high or max. Use null for models without reasoning effort." }, "temperature": { "type": "number", "minimum": 0.0, "title": "Temperature" }, "max_tokens": { "type": "integer", "minimum": 1.0, "title": "Max Tokens" }, "request_timeout": { "type": "integer", "minimum": 1.0, "title": "Request Timeout" }, "system_prompts": { "additionalProperties": { "type": "string" }, "type": "object", "title": "System Prompts" } }, "type": "object", "title": "LLMConfigPayload" }, "LLMConfigResponse": { "properties": { "active_provider": { "type": "string", "title": "Active Provider" }, "active_model": { "type": "string", "title": "Active Model" }, "providers": { "additionalProperties": { "$ref": "#/components/schemas/ProviderInfo" }, "type": "object", "title": "Providers" }, "api_key": { "type": "string", "title": "Api Key" }, "temperature": { "type": "number", "title": "Temperature" }, "system_prompts": { "additionalProperties": { "type": "string" }, "type": "object", "title": "System Prompts" }, "reasoning_effort": { "type": "string", "title": "Reasoning Effort" }, "max_tokens": { "type": "integer", "title": "Max Tokens" }, "request_timeout": { "type": "integer", "title": "Request Timeout" } }, "type": "object", "required": [ "active_provider", "active_model", "providers", "temperature", "system_prompts", "max_tokens", "request_timeout" ], "title": "LLMConfigResponse" }, "LoginRequest": { "properties": { "email": { "type": "string", "title": "Email" }, "password": { "type": "string", "title": "Password" } }, "type": "object", "required": ["email", "password"], "title": "LoginRequest", "description": "POST /auth/login — body." }, "LoginResponse": { "properties": { "token": { "type": "string", "title": "Token" }, "user": { "$ref": "#/components/schemas/UserResponse" } }, "type": "object", "required": ["token", "user"], "title": "LoginResponse", "description": "POST /auth/login and POST /auth/login/api-key — 200 response." }, "PaginationDTO": { "properties": { "page": { "type": "integer", "title": "Page" }, "limit": { "type": "integer", "title": "Limit" }, "total": { "type": "integer", "title": "Total" }, "total_pages": { "type": "integer", "title": "Total Pages" } }, "type": "object", "required": ["page", "limit", "total", "total_pages"], "title": "PaginationDTO" }, "PatchUser": { "properties": { "email": { "type": "string", "format": "email", "title": "Email" }, "name": { "type": "string", "title": "Name" }, "phone": { "type": "integer", "title": "Phone" }, "role": { "$ref": "#/components/schemas/app__schema__auth_schema__Role" }, "is_active": { "type": "boolean", "title": "Is Active" }, "password": { "type": "string", "title": "Password" } }, "additionalProperties": false, "type": "object", "title": "PatchUser", "description": "PATCH user untuk admin: semua field opsional agar bisa edit parsial.\n\nDilarang mengubah: id, user_token." }, "ProviderInfo": { "properties": { "base_url": { "type": "string", "title": "Base Url" }, "model_options": { "items": { "type": "string" }, "type": "array", "title": "Model Options" } }, "type": "object", "required": ["model_options"], "title": "ProviderInfo" }, "ProviderInfoPayload": { "properties": { "base_url": { "type": "string", "title": "Base Url" }, "model_options": { "items": { "type": "string" }, "type": "array", "title": "Model Options" } }, "type": "object", "title": "ProviderInfoPayload" }, "RAGConfigResponse": { "properties": { "path": { "type": "string", "title": "Path" }, "llm_config": { "$ref": "#/components/schemas/LLMConfigResponse" }, "vector_db": { "$ref": "#/components/schemas/VectorDBConfigResponse" }, "retrieval": { "$ref": "#/components/schemas/RetrievalConfigResponse" } }, "type": "object", "required": ["path", "llm_config", "vector_db", "retrieval"], "title": "RAGConfigResponse" }, "RegisterRequest": { "properties": { "email": { "type": "string", "title": "Email" }, "password": { "type": "string", "minLength": 6, "title": "Password" }, "name": { "type": "string", "title": "Name" }, "phone": { "type": "string", "title": "Phone" }, "role": { "$ref": "#/components/schemas/app__schema__auth_schema__Role" }, "identity_number": { "type": "string", "pattern": "^[0-9]+$", "title": "Identity Number", "description": "Student ID (NIM) or Lecturer ID (NIP) – numbers only" } }, "type": "object", "required": [ "email", "password", "name", "role", "identity_number" ], "title": "RegisterRequest", "description": "POST /auth/register — body." }, "RegisterResponse": { "properties": { "message": { "type": "string", "title": "Message" }, "user": { "$ref": "#/components/schemas/UserResponse" } }, "type": "object", "required": ["message", "user"], "title": "RegisterResponse", "description": "POST /auth/register — 201 response." }, "RetrievalConfigPayload": { "properties": { "top_k": { "type": "integer", "minimum": 1.0, "title": "Top K" }, "bm25_weight": { "type": "number", "maximum": 1.0, "minimum": 0.0, "title": "Bm25 Weight" }, "dense_weight": { "type": "number", "maximum": 1.0, "minimum": 0.0, "title": "Dense Weight" }, "lexical_weight": { "type": "number", "maximum": 1.0, "minimum": 0.0, "title": "Lexical Weight" }, "enable_reranker": { "type": "boolean", "title": "Enable Reranker" }, "reranker_model": { "type": "string", "minLength": 1, "title": "Reranker Model" }, "max_context_chars": { "type": "integer", "minimum": 1.0, "title": "Max Context Chars" }, "similarity_threshold": { "type": "number", "minimum": 0.0, "title": "Similarity Threshold" }, "history_turns": { "type": "integer", "minimum": 0.0, "title": "History Turns" }, "candidate_pool_size": { "type": "integer", "minimum": 1.0, "title": "Candidate Pool Size" }, "neighbor_window": { "type": "integer", "minimum": 0.0, "title": "Neighbor Window" } }, "type": "object", "title": "RetrievalConfigPayload" }, "RetrievalConfigResponse": { "properties": { "top_k": { "type": "integer", "title": "Top K" }, "bm25_weight": { "type": "number", "title": "Bm25 Weight" }, "dense_weight": { "type": "number", "title": "Dense Weight" }, "lexical_weight": { "type": "number", "title": "Lexical Weight" }, "enable_reranker": { "type": "boolean", "title": "Enable Reranker" }, "reranker_model": { "type": "string", "title": "Reranker Model" }, "max_context_chars": { "type": "integer", "title": "Max Context Chars" }, "similarity_threshold": { "type": "number", "title": "Similarity Threshold" }, "history_turns": { "type": "integer", "title": "History Turns" }, "candidate_pool_size": { "type": "integer", "title": "Candidate Pool Size" }, "neighbor_window": { "type": "integer", "title": "Neighbor Window" } }, "type": "object", "required": [ "top_k", "bm25_weight", "dense_weight", "lexical_weight", "enable_reranker", "reranker_model", "max_context_chars", "similarity_threshold", "history_turns", "candidate_pool_size", "neighbor_window" ], "title": "RetrievalConfigResponse" }, "SearchOptions": { "properties": { "ordering": { "type": "string", "title": "Ordering" }, "page": { "type": "integer", "title": "Page" }, "page_size": { "anyOf": [ { "type": "integer" }, { "type": "string" } ], "title": "Page Size" }, "total_count": { "type": "integer", "title": "Total Count" } }, "type": "object", "title": "SearchOptions" }, "UpdateCourseRequest": { "properties": { "title": { "type": "string", "title": "Title" }, "description": { "type": "string", "title": "Description" } }, "type": "object", "title": "UpdateCourseRequest" }, "UploadDocumentResponse": { "properties": { "document_id": { "type": "string", "title": "Document Id" }, "filename": { "type": "string", "title": "Filename" }, "status": { "$ref": "#/components/schemas/DocumentStatus" }, "message": { "type": "string", "title": "Message" } }, "type": "object", "required": ["document_id", "filename", "status", "message"], "title": "UploadDocumentResponse", "description": "POST /documents/upload — 202 Accepted response.\nSource: openapi-spec.yml /documents/upload 202 schema" }, "UpsertWhitelist": { "properties": { "source_type": { "type": "string", "title": "Source Type" }, "value": { "type": "string", "title": "Value" }, "description": { "type": "string", "title": "Description" }, "is_active": { "type": "boolean", "title": "Is Active", "default": true } }, "type": "object", "required": ["source_type", "value"], "title": "UpsertWhitelist" }, "User": { "properties": { "email": { "type": "string", "title": "Email" }, "name": { "type": "string", "title": "Name" }, "phone": { "type": "string", "title": "Phone" }, "role": { "$ref": "#/components/schemas/app__schema__user_schema__Role" }, "identity_number": { "type": "string", "title": "Identity Number" }, "is_active": { "type": "boolean", "title": "Is Active" }, "is_superuser": { "type": "boolean", "title": "Is Superuser" }, "id": { "type": "integer", "title": "Id" }, "created_at": { "type": "string", "format": "date-time", "title": "Created At" }, "updated_at": { "type": "string", "format": "date-time", "title": "Updated At" }, "user_token": { "type": "string", "title": "User Token" } }, "type": "object", "title": "User" }, "UserResponse": { "properties": { "id": { "type": "integer", "title": "Id" }, "identity_number": { "type": "string", "title": "Identity Number" }, "name": { "type": "string", "title": "Name" }, "phone": { "type": "string", "title": "Phone" }, "role": { "$ref": "#/components/schemas/app__schema__auth_schema__Role" }, "email": { "type": "string", "title": "Email" }, "status": { "$ref": "#/components/schemas/UserStatus" }, "created_at": { "type": "string", "format": "date-time", "title": "Created At" }, "updated_at": { "type": "string", "format": "date-time", "title": "Updated At" } }, "type": "object", "required": [ "id", "identity_number", "role", "email", "status", "created_at", "updated_at" ], "title": "UserResponse", "description": "Mirrors the OpenAPI `User` schema.\nMaps `is_active: bool` → `status: active|inactive` at serialization time.\n[ENGINEERING DECISION] DB column stays as `is_active` to avoid a migration\nbreaking change; the mapping is handled here in the Pydantic layer." }, "UserStatus": { "type": "string", "enum": ["active", "inactive"], "title": "UserStatus", "description": "An enumeration." }, "ValidationError": { "properties": { "loc": { "items": { "anyOf": [ { "type": "string" }, { "type": "integer" } ] }, "type": "array", "title": "Location" }, "msg": { "type": "string", "title": "Message" }, "type": { "type": "string", "title": "Error Type" } }, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError" }, "VectorDBConfigPayload": { "properties": { "embedding_model": { "type": "string", "minLength": 1, "title": "Embedding Model" }, "chunk_size": { "type": "integer", "minimum": 1.0, "title": "Chunk Size" }, "chunk_overlap": { "type": "integer", "minimum": 0.0, "title": "Chunk Overlap" }, "persist_path": { "type": "string", "title": "Persist Path" } }, "type": "object", "title": "VectorDBConfigPayload" }, "VectorDBConfigResponse": { "properties": { "embedding_model": { "type": "string", "title": "Embedding Model" }, "chunk_size": { "type": "integer", "title": "Chunk Size" }, "chunk_overlap": { "type": "integer", "title": "Chunk Overlap" }, "persist_path": { "type": "string", "title": "Persist Path" } }, "type": "object", "required": ["embedding_model", "chunk_size", "chunk_overlap"], "title": "VectorDBConfigResponse" }, "app__schema__auth_schema__Role": { "type": "string", "enum": ["admin", "student", "lecturer"], "title": "Role", "description": "An enumeration." }, "app__schema__user_schema__Role": { "type": "string", "enum": ["admin", "student", "lecturer"], "title": "Role", "description": "An enumeration." } }, "securitySchemes": { "JWTBearer": { "type": "http", "scheme": "bearer" } } } }