{"openapi":"3.1.0","info":{"title":"AI Quick Transcript App","description":"API for transcribing and summarizing audio/video files, managing API keys, handling payments, and redeeming vouchers.","version":"1.0.0"},"paths":{"/api/keys/test":{"get":{"tags":["api_keys"],"summary":"Test Api Keys Router","operationId":"test_api_keys_router_api_keys_test_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/keys":{"get":{"tags":["api_keys"],"summary":"List Api Keys","description":"Lists metadata for the authenticated user's API keys.","operationId":"list_api_keys_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["api_keys"],"summary":"Create Api Key","description":"Generates a new API key for the authenticated user (requires standard login).","operationId":"create_api_key_api_keys_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_create_api_key_api_keys_post"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keys/{key_id}":{"delete":{"tags":["api_keys"],"summary":"Revoke Api Key","description":"Revokes (deletes) an API key belonging to the authenticated user.","operationId":"revoke_api_key_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/test":{"get":{"tags":["auth"],"summary":"Test API Key Authentication","description":"Endpoint for Zapier (or other clients) to test API Key authentication.\nIf the request reaches here with a valid API key in the X-API-Key header,\nit means the key is valid. Returns the authenticated user's email.","operationId":"test_api_key_authentication_api_auth_test_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTestResponse"}}}},"401":{"description":"Authentication failed (e.g., missing, invalid, or inactive API key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPErrorDetail"}}}}}}},"/api/transcriptions":{"post":{"tags":["transcriptions"],"summary":"Submit Transcription Job","description":"Upload an audio or video file for transcription.\n\nSend the request as `multipart/form-data` (required for file uploads) or\n`application/x-www-form-urlencoded` with exactly one of:\n\n- `file`: the media file, with an `audio/*` or `video/*` content type\n- `file_url`: a publicly reachable URL of an audio or video file\n\nJSON request bodies are not accepted.\n\nSet `summarize=false` for transcription only. If omitted, `summarize` defaults\nto `true` and generates both the transcription and an AI summary. Completed\ntranscription-only jobs return `summary_html: null`.\n\nReturns a `task_id` that can be polled via `GET /api/transcriptions/{task_id}`.\nAuthentication via API-Key (X-API-Key) or Firebase ID token is required.","operationId":"create_transcription_job_api_transcriptions_post","parameters":[{"name":"summarize","in":"query","required":false,"schema":{"type":"boolean","description":"Generate an AI summary. Set to false for transcription only.","default":true,"title":"Summarize"},"description":"Generate an AI summary. Set to false for transcription only."}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_transcription_job_api_transcriptions_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTranscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/completed":{"get":{"tags":["transcriptions"],"summary":"Get Completed Transcriptions (Polling)","description":"Retrieves completed transcription tasks for the authenticated user\nthat have not yet been processed by a polling mechanism (like Zapier).\n\nThis endpoint is designed for polling triggers. It retrieves tasks,\nmarks them as 'seen' (by setting `zapier_seen_at`), and returns their results.\nAuthentication via API Key (X-API-Key header) is required.","operationId":"get_completed_transcriptions_api_transcriptions_completed_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum number of completed transcriptions to return per poll.","default":10,"title":"Limit"},"description":"Maximum number of completed transcriptions to return per poll."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompletedTranscription"},"title":"Response Get Completed Transcriptions Api Transcriptions Completed Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transcriptions/{task_id}":{"get":{"tags":["transcriptions"],"summary":"Get Transcription Task Status","description":"Poll the status of a transcription job by its `task_id`.\nWhen `status` becomes `\"complete\"` the `result` field contains the full data.","operationId":"get_transcription_status_api_transcriptions__task_id__get","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Get Index","description":"Serves the main HTML page, passing Firebase config to the template.","operationId":"get_index__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api-docs":{"get":{"tags":["Documentation"],"summary":"Get Api Documentation Page","description":"Serves the API documentation landing page with links to Swagger and ReDoc.","operationId":"get_api_documentation_page_api_docs_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/llm-instructions":{"get":{"tags":["Documentation"],"summary":"Get Llm Instructions Page","description":"Serves integration instructions and examples written for LLMs and AI agents.","operationId":"get_llm_instructions_page_llm_instructions_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/mcp-integration":{"get":{"tags":["Documentation"],"summary":"Get Mcp Integration Page","description":"Serves the MCP integration overview for Claude, ChatGPT, and other clients.","operationId":"get_mcp_integration_page_mcp_integration_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/api/meetings":{"get":{"tags":["meetings"],"summary":"List Meetings","operationId":"list_meetings_api_meetings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["meetings"],"summary":"Start Meeting","operationId":"start_meeting_api_meetings_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeetingStartRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/meetings/{task_id}":{"get":{"tags":["meetings"],"summary":"Get Meeting","operationId":"get_meeting_api_meetings__task_id__get","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/meetings/{task_id}/stop":{"post":{"tags":["meetings"],"summary":"Stop Meeting","operationId":"stop_meeting_api_meetings__task_id__stop_post","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/credits":{"get":{"tags":["credits"],"summary":"Check credit balance","description":"Return the authenticated user's credits without consuming them.","operationId":"get_credit_balance_api_credits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"integer"},"type":"object","title":"Response Get Credit Balance Api Credits Get"}}}}}}},"/api/user/status":{"get":{"summary":"Get User Status","description":"Get current user's status including authentication state, role, and permissions.\nReplaces client-side hardcoded admin checks.","operationId":"get_user_status_api_user_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserStatusResponse"}}}}}}},"/api/user/admin-status":{"get":{"summary":"Get Admin Status","description":"Check if the current user has admin privileges.\nLightweight endpoint for admin UI visibility.","operationId":"get_admin_status_api_user_admin_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminStatusResponse"}}}}}}},"/api/user/check-permission":{"post":{"summary":"Check Permission","description":"Check if the current user has a specific permission.","operationId":"check_permission_api_user_check_permission_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionCheckRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/user/permissions":{"get":{"summary":"Get User Permissions","description":"Get all permissions for the current user.","operationId":"get_user_permissions_api_user_permissions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response Get User Permissions Api User Permissions Get"}}}}}}},"/api/admin/roles/assign":{"post":{"summary":"Assign Role","description":"Assign a role to a user.\nRequires MANAGE_ROLES permission.","operationId":"assign_role_api_admin_roles_assign_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignmentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/roles/revoke":{"post":{"summary":"Revoke Role","description":"Revoke a user's role.\nRequires MANAGE_ROLES permission.","operationId":"revoke_role_api_admin_roles_revoke_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRevokeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/roles/list":{"get":{"summary":"List User Roles","description":"List all user roles.\nRequires VIEW_USERS permission.","operationId":"list_user_roles_api_admin_roles_list_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/roles/audit":{"get":{"summary":"Get Audit Log","description":"Get audit log entries for role-related actions.\nRequires VIEW_AUDIT_LOGS permission.","operationId":"get_audit_log_api_admin_roles_audit_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/roles/user/{user_id}":{"get":{"summary":"Get User Role","description":"Get a specific user's role.\nRequires VIEW_USERS permission.","operationId":"get_user_role_api_admin_roles_user__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRole"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/roles/available":{"get":{"summary":"Get Available Roles","description":"Get list of available roles and their descriptions.\nRequires VIEW_USERS permission.","operationId":"get_available_roles_api_admin_roles_available_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Response Get Available Roles Api Admin Roles Available Get"}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Health check endpoint for Docker healthcheck.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AdminStatusResponse":{"properties":{"is_admin":{"type":"boolean","title":"Is Admin"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions","default":[]}},"type":"object","required":["is_admin"],"title":"AdminStatusResponse","description":"Response model for admin status check."},"AuditLogEntry":{"properties":{"id":{"type":"string","title":"Id"},"user_id":{"type":"string","title":"User Id"},"user_email":{"type":"string","title":"User Email"},"action":{"type":"string","title":"Action"},"resource_type":{"type":"string","title":"Resource Type"},"resource_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Id"},"details":{"additionalProperties":true,"type":"object","title":"Details"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"success":{"type":"boolean","title":"Success","default":true},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["id","user_id","user_email","action","resource_type"],"title":"AuditLogEntry","description":"Audit log entry for admin actions."},"AuditLogResponse":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/AuditLogEntry"},"type":"array","title":"Entries"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["entries","total"],"title":"AuditLogResponse","description":"Response model for audit log entries."},"AuthTestResponse":{"properties":{"authenticated":{"type":"boolean","title":"Authenticated","description":"Indicates successful authentication.","default":true},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email","description":"The account email when available; API key authentication does not require it."}},"type":"object","title":"AuthTestResponse","description":"Schema for the successful response of the authentication test endpoint.","example":{"authenticated":true}},"Body_create_api_key_api_keys_post":{"properties":{"label":{"type":"string","title":"Label"}},"type":"object","required":["label"],"title":"Body_create_api_key_api_keys_post"},"Body_create_transcription_job_api_transcriptions_post":{"properties":{"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File","description":"Audio or video file to transcribe."},"file_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Url","description":"Publicly reachable URL of an audio or video file."},"file_url_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Url Form","description":"Deprecated alias of `file_url`."}},"type":"object","title":"Body_create_transcription_job_api_transcriptions_post"},"CompletedTranscription":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier for the task record (Firestore document ID)."},"task_id":{"type":"string","title":"Task Id","description":"The original UUID assigned to the task during creation."},"original_filename":{"type":"string","title":"Original Filename","description":"The name of the uploaded file."},"completed_at":{"type":"string","title":"Completed At","description":"ISO 8601 timestamp indicating when the task finished processing."},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds","description":"Length of the processed audio/video in seconds."},"transcription":{"anyOf":[{"items":{"$ref":"#/components/schemas/TranscriptionSegment"},"type":"array"},{"type":"null"}],"title":"Transcription","description":"List of transcribed segments with timestamps."},"summary_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Html","description":"AI-generated summary of the transcription in HTML format."},"final_credit_cost":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Final Credit Cost","description":"Number of credits deducted for this task (if applicable)."},"total_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tokens","description":"Total tokens processed by the AI model (if applicable)."}},"type":"object","required":["id","task_id","original_filename","completed_at"],"title":"CompletedTranscription","description":"Schema for a completed transcription task returned by the API.","example":{"completed_at":"2024-08-15T10:30:00.123000+00:00","duration_seconds":175.5,"final_credit_cost":2,"id":"firestoreDocId123","summary_html":"<p>The meeting discussed the <strong>quarterly results</strong>.</p>","task_id":"a1b2c3d4-e5f6-7890-1234-567890abcdef","total_tokens":1500,"transcription":[{"text":"Okay, let's get started.","timestamp":"[00:00]"},{"text":"The main topic today is the quarterly results.","timestamp":"[00:05]"}]}},"CreateTranscriptionResponse":{"properties":{"task_id":{"type":"string","title":"Task Id","description":"Identifier to poll with GET /api/transcriptions/{task_id}"},"status":{"type":"string","title":"Status","description":"Initial job status (always 'pending').","default":"pending"}},"type":"object","required":["task_id"],"title":"CreateTranscriptionResponse","description":"Response returned right after a job is accepted."},"HTTPErrorDetail":{"properties":{"detail":{"type":"string","title":"Detail","description":"Details about the HTTP error."}},"type":"object","required":["detail"],"title":"HTTPErrorDetail","description":"Generic schema for HTTP error responses.","example":{"detail":"Authentication required."}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"MeetingStartRequest":{"properties":{"request_id":{"type":"string","format":"uuid","title":"Request Id"},"meeting_url":{"type":"string","title":"Meeting Url"},"consent_confirmed":{"type":"boolean","title":"Consent Confirmed"},"summarize":{"type":"boolean","title":"Summarize","default":true},"prefer_timestamps":{"type":"boolean","title":"Prefer Timestamps","default":false},"max_duration_minutes":{"type":"integer","title":"Max Duration Minutes","default":120}},"type":"object","required":["request_id","meeting_url","consent_confirmed"],"title":"MeetingStartRequest"},"PermissionCheckRequest":{"properties":{"permission":{"type":"string","title":"Permission"}},"type":"object","required":["permission"],"title":"PermissionCheckRequest","description":"Request model for permission checking."},"PermissionCheckResponse":{"properties":{"has_permission":{"type":"boolean","title":"Has Permission"},"permission":{"type":"string","title":"Permission"}},"type":"object","required":["has_permission","permission"],"title":"PermissionCheckResponse","description":"Response model for permission check."},"RoleAssignmentRequest":{"properties":{"user_email":{"type":"string","title":"User Email"},"role":{"$ref":"#/components/schemas/RoleType"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["user_email","role"],"title":"RoleAssignmentRequest","description":"Request model for role assignment."},"RoleAssignmentResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"user_role":{"anyOf":[{"$ref":"#/components/schemas/UserRole"},{"type":"null"}]}},"type":"object","required":["success","message"],"title":"RoleAssignmentResponse","description":"Response model for role assignment."},"RoleListResponse":{"properties":{"roles":{"items":{"$ref":"#/components/schemas/UserRole"},"type":"array","title":"Roles"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["roles","total"],"title":"RoleListResponse","description":"Response model for role listing."},"RoleRevokeRequest":{"properties":{"user_id":{"type":"string","title":"User Id"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["user_id"],"title":"RoleRevokeRequest","description":"Request model for role revocation."},"RoleType":{"type":"string","enum":["super_admin","admin","moderator","support","user"],"title":"RoleType","description":"Define role hierarchy levels."},"TaskStatusResponse":{"properties":{"task_id":{"type":"string","title":"Task Id"},"status":{"type":"string","title":"Status"},"status_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Message"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message","description":"User-facing failure reason when status is 'failed'."},"error_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Type","description":"Failure category when status is 'failed': 'file_error', 'download_error', 'prohibited_content', 'insufficient_credits', 'meeting_error', or 'processing_error'."},"result":{"anyOf":[{"$ref":"#/components/schemas/CompletedTranscription"},{"type":"null"}]}},"type":"object","required":["task_id","status"],"title":"TaskStatusResponse","description":"JSON status payload for a transcription job."},"TranscriptionSegment":{"properties":{"timestamp":{"type":"string","title":"Timestamp","description":"Segment start as '[MM:SS]' or '[HH:MM:SS]' (e.g., '[01:05]')."},"text":{"type":"string","title":"Text","description":"The transcribed text for this segment."}},"type":"object","required":["timestamp","text"],"title":"TranscriptionSegment","description":"Represents a single segment of the transcription."},"UserRole":{"properties":{"user_id":{"type":"string","title":"User Id"},"user_email":{"type":"string","title":"User Email"},"role":{"$ref":"#/components/schemas/RoleType"},"granted_by":{"type":"string","title":"Granted By"},"granted_at":{"type":"string","format":"date-time","title":"Granted At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"is_active":{"type":"boolean","title":"Is Active","default":true},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["user_id","user_email","role","granted_by"],"title":"UserRole","description":"User role assignment with time-based access controls."},"UserStatusResponse":{"properties":{"is_authenticated":{"type":"boolean","title":"Is Authenticated"},"is_admin":{"type":"boolean","title":"Is Admin"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions","default":[]}},"type":"object","required":["is_authenticated","is_admin"],"title":"UserStatusResponse","description":"Response model for user status information."},"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"}}}}