...
" + description: 'Full policy content as HTML' + example: '...
' status: type: string - description: "Policy lifecycle status" + description: 'Policy lifecycle status' example: draft tags: type: array items: type: string enum: - - "AI ethics" + - 'AI ethics' - Fairness - Transparency - Explainability - - "Bias mitigation" + - 'Bias mitigation' - Privacy - - "Data governance" - - "Model risk" + - 'Data governance' + - 'Model risk' - Accountability - Security - LLM - - "Human oversight" - - "EU AI Act" - - "ISO 42001" - - "NIST RMF" - - "Red teaming" + - 'Human oversight' + - 'EU AI Act' + - 'ISO 42001' + - 'NIST RMF' + - 'Red teaming' - Audit - Monitoring - - "Vendor management" - description: "Categorization tags" + - 'Vendor management' + description: 'Categorization tags' next_review_date: type: string format: date-time nullable: true - description: "Scheduled next review date" + description: 'Scheduled next review date' author_id: type: integer - description: "User ID of the policy creator" + description: 'User ID of the policy creator' example: 1 last_updated_by: type: integer - description: "User ID of the last editor" + description: 'User ID of the last editor' example: 1 last_updated_at: type: string format: date-time - description: "Timestamp of last update" + description: 'Timestamp of last update' review_status: type: string nullable: true @@ -1210,33 +1223,33 @@ components: - approved - changes_requested - null - description: "Current review workflow status" + description: 'Current review workflow status' review_comment: type: string nullable: true - description: "Most recent review comment" + description: 'Most recent review comment' reviewed_by: type: integer nullable: true - description: "User ID of the last reviewer" + description: 'User ID of the last reviewer' reviewed_at: type: string format: date-time nullable: true - description: "Timestamp of last review action" + description: 'Timestamp of last review action' is_demo: type: boolean - description: "Whether this is a demo/seed policy" + description: 'Whether this is a demo/seed policy' default: false created_at: type: string format: date-time - description: "Row creation timestamp (set by database)" + description: 'Row creation timestamp (set by database)' assigned_reviewer_ids: type: array items: type: integer - description: "User IDs of assigned reviewers (aggregated from mapping table)" + description: 'User IDs of assigned reviewers (aggregated from mapping table)' example: - 2 - 5 @@ -1249,70 +1262,70 @@ components: properties: title: type: string - description: "Policy title" - example: "Data Governance Policy" + description: 'Policy title' + example: 'Data Governance Policy' content_html: type: string - description: "Full policy content as HTML" - example: "This policy outlines...
" + description: 'Full policy content as HTML' + example: 'This policy outlines...
' status: type: string - description: "Initial policy status" + description: 'Initial policy status' example: draft tags: type: array items: type: string - description: "Categorization tags (must be from the allowed tag list)" + description: 'Categorization tags (must be from the allowed tag list)' example: - - "Data governance" + - 'Data governance' - Privacy next_review_date: type: string format: date-time nullable: true - description: "Scheduled next review date" - example: "2026-07-01T00:00:00.000Z" + description: 'Scheduled next review date' + example: '2026-07-01T00:00:00.000Z' assigned_reviewer_ids: type: array items: type: integer - description: "User IDs to assign as reviewers" + description: 'User IDs to assign as reviewers' example: - 2 - 5 is_demo: type: boolean - description: "Mark as a demo policy" + description: 'Mark as a demo policy' default: false PolicyUpdateRequest: type: object - description: "All fields are optional. Only provided fields are updated." + description: 'All fields are optional. Only provided fields are updated.' properties: title: type: string - description: "Updated policy title" + description: 'Updated policy title' content_html: type: string - description: "Updated policy content as HTML" + description: 'Updated policy content as HTML' status: type: string - description: "Updated policy status" + description: 'Updated policy status' tags: type: array items: type: string - description: "Replacement tag list (must be from the allowed tag list)" + description: 'Replacement tag list (must be from the allowed tag list)' next_review_date: type: string format: date-time nullable: true - description: "Updated next review date" + description: 'Updated next review date' assigned_reviewer_ids: type: array items: type: integer - description: "Replacement reviewer list (fully replaces existing reviewers)" + description: 'Replacement reviewer list (fully replaces existing reviewers)' ProjectRiskInput: type: object required: @@ -1322,28 +1335,28 @@ components: properties: risk_name: type: string - description: "Name/title of the risk." + description: 'Name/title of the risk.' risk_owner: type: integer - description: "User ID of the risk owner (must be >= 1)." + description: 'User ID of the risk owner (must be >= 1).' ai_lifecycle_phase: type: string enum: - - "Problem definition & planning" - - "Data collection & processing" - - "Model development & training" - - "Model validation & testing" - - "Deployment & integration" - - "Monitoring & maintenance" - - "Decommissioning & retirement" + - 'Problem definition & planning' + - 'Data collection & processing' + - 'Model development & training' + - 'Model validation & testing' + - 'Deployment & integration' + - 'Monitoring & maintenance' + - 'Decommissioning & retirement' risk_description: type: string - description: "Detailed description of the risk." + description: 'Detailed description of the risk.' risk_category: type: array items: type: string - description: "Array of category labels." + description: 'Array of category labels.' impact: type: string assessment_mapping: @@ -1357,7 +1370,7 @@ components: - Unlikely - Possible - Likely - - "Almost Certain" + - 'Almost Certain' severity: type: string enum: @@ -1369,32 +1382,32 @@ components: risk_level_autocalculated: type: string enum: - - "No risk" - - "Very low risk" - - "Low risk" - - "Medium risk" - - "High risk" - - "Very high risk" + - 'No risk' + - 'Very low risk' + - 'Low risk' + - 'Medium risk' + - 'High risk' + - 'Very high risk' review_notes: type: string mitigation_status: type: string enum: - - "Not Started" - - "In Progress" + - 'Not Started' + - 'In Progress' - Completed - - "On Hold" + - 'On Hold' - Deferred - Canceled - - "Requires review" + - 'Requires review' current_risk_level: type: string enum: - - "Very Low risk" - - "Low risk" - - "Medium risk" - - "High risk" - - "Very high risk" + - 'Very Low risk' + - 'Low risk' + - 'Medium risk' + - 'High risk' + - 'Very high risk' deadline: type: string format: date-time @@ -1411,7 +1424,7 @@ components: - Unlikely - Possible - Likely - - "Almost Certain" + - 'Almost Certain' risk_severity: type: string enum: @@ -1424,7 +1437,7 @@ components: type: string risk_approval: type: integer - description: "User ID of the approver." + description: 'User ID of the approver.' approval_status: type: string date_of_assessment: @@ -1437,12 +1450,12 @@ components: type: array items: type: integer - description: "Array of project IDs to link this risk to." + description: 'Array of project IDs to link this risk to.' frameworks: type: array items: type: integer - description: "Array of framework IDs to link this risk to." + description: 'Array of framework IDs to link this risk to.' event_frequency_min: type: number nullable: true @@ -1491,7 +1504,7 @@ components: control_effectiveness: type: number nullable: true - description: "Percentage 0-100." + description: 'Percentage 0-100.' mitigation_cost_annual: type: number nullable: true @@ -1505,8 +1518,10 @@ components: maxLength: 3 ProjectRiskResponse: allOf: - - $ref: "#/components/schemas/ProjectRiskInput" - - type: object + - + $ref: '#/components/schemas/ProjectRiskInput' + - + type: object properties: id: type: integer @@ -1574,11 +1589,11 @@ components: properties: vendor_id: type: integer - description: "ID of the vendor this risk belongs to." + description: 'ID of the vendor this risk belongs to.' order_no: type: integer nullable: true - description: "Optional ordering number." + description: 'Optional ordering number.' risk_description: type: string impact_description: @@ -1590,7 +1605,7 @@ components: - Unlikely - Possible - Likely - - "Almost certain" + - 'Almost certain' risk_severity: type: string enum: @@ -1603,10 +1618,10 @@ components: type: string action_owner: type: integer - description: "User ID of the action owner." + description: 'User ID of the action owner.' risk_level: type: string - description: "Free-text risk level." + description: 'Free-text risk level.' is_demo: type: boolean default: false @@ -1634,7 +1649,7 @@ components: - Unlikely - Possible - Likely - - "Almost certain" + - 'Almost certain' risk_severity: type: string enum: @@ -1658,7 +1673,7 @@ components: type: string format: date-time VendorRiskAllProjectsResponse: - description: "Extended vendor risk with joined vendor/project info." + description: 'Extended vendor risk with joined vendor/project info.' type: object properties: risk_id: @@ -1719,9 +1734,9 @@ components: type: string enum: - Performance - - "Bias & Fairness" + - 'Bias & Fairness' - Security - - "Data Quality" + - 'Data Quality' - Compliance risk_level: type: string @@ -1734,17 +1749,17 @@ components: type: string enum: - Open - - "In Progress" + - 'In Progress' - Resolved - Accepted default: Open owner: type: string - description: "Name or identifier of the risk owner." + description: 'Name or identifier of the risk owner.' target_date: type: string format: date - description: "Next review / target date." + description: 'Next review / target date.' description: type: string mitigation_plan: @@ -1762,7 +1777,7 @@ components: model_id: type: integer nullable: true - description: "ID of the model inventory entry this risk is linked to." + description: 'ID of the model inventory entry this risk is linked to.' is_demo: type: boolean default: false @@ -1777,9 +1792,9 @@ components: type: string enum: - Performance - - "Bias & Fairness" + - 'Bias & Fairness' - Security - - "Data Quality" + - 'Data Quality' - Compliance risk_level: type: string @@ -1792,7 +1807,7 @@ components: type: string enum: - Open - - "In Progress" + - 'In Progress' - Resolved - Accepted owner: @@ -1830,7 +1845,7 @@ components: type: string example: success data: - description: "Response payload (type varies per endpoint)" + description: 'Response payload (type varies per endpoint)' ValidationErrorResponse: type: object properties: @@ -1839,7 +1854,7 @@ components: example: error message: type: string - example: "Dataset creation validation failed" + example: 'Dataset creation validation failed' errors: type: array items: @@ -1866,7 +1881,7 @@ components: evidence_files: type: array items: - $ref: "#/components/schemas/FileResponse" + $ref: '#/components/schemas/FileResponse' expiry_date: type: string format: date-time @@ -1887,14 +1902,18 @@ components: properties: id: oneOf: - - type: string - - type: integer + - + type: string + - + type: integer filename: type: string size: oneOf: - - type: number - - type: string + - + type: number + - + type: string mimetype: type: string uploaded_by: @@ -1923,9 +1942,9 @@ components: properties: id: oneOf: - - { type: string } - - { type: integer } - description: "Array of file references (by ID) to link" + - {type: string} + - {type: integer} + description: 'Array of file references (by ID) to link' expiry_date: type: string format: date-time @@ -1934,7 +1953,7 @@ components: type: array items: type: integer - description: "Model inventory IDs to map this evidence to" + description: 'Model inventory IDs to map this evidence to' EvidenceUpdateRequest: type: object properties: @@ -1954,16 +1973,18 @@ components: properties: id: oneOf: - - { type: string } - - { type: integer } - description: "New files to link" + - {type: string} + - {type: integer} + description: 'New files to link' deleteFiles: type: array items: oneOf: - - type: string - - type: integer - description: "File IDs to unlink" + - + type: string + - + type: integer + description: 'File IDs to unlink' expiry_date: type: string format: date-time @@ -2041,7 +2062,7 @@ components: documentation_data: type: array items: - $ref: "#/components/schemas/DocumentationFile" + $ref: '#/components/schemas/DocumentationFile' is_demo: type: boolean created_at: @@ -2054,15 +2075,15 @@ components: type: array items: type: integer - description: "Related model inventory IDs" + description: 'Related model inventory IDs' projects: type: array items: type: integer - description: "Related project IDs" + description: 'Related project IDs' DocumentationFile: type: object - description: "File metadata stored in JSONB documentation_data column" + description: 'File metadata stored in JSONB documentation_data column' properties: id: type: string @@ -2138,7 +2159,7 @@ components: status_date: type: string format: date-time - description: "Defaults to current time if omitted" + description: 'Defaults to current time if omitted' known_biases: type: string bias_mitigation: @@ -2150,7 +2171,7 @@ components: documentation_data: type: array items: - $ref: "#/components/schemas/DocumentationFile" + $ref: '#/components/schemas/DocumentationFile' is_demo: type: boolean default: false @@ -2158,15 +2179,15 @@ components: type: array items: type: integer - description: "Model inventory IDs to associate" + description: 'Model inventory IDs to associate' projects: type: array items: type: integer - description: "Project IDs to associate" + description: 'Project IDs to associate' DatasetUpdateRequest: type: object - description: "All fields optional. Only provided fields are updated." + description: 'All fields optional. Only provided fields are updated.' properties: name: type: string @@ -2231,25 +2252,25 @@ components: documentation_data: type: array items: - $ref: "#/components/schemas/DocumentationFile" + $ref: '#/components/schemas/DocumentationFile' is_demo: type: boolean models: type: array items: type: integer - description: "Replace model associations (provide full list)" + description: 'Replace model associations (provide full list)' projects: type: array items: type: integer - description: "Replace project associations (provide full list)" + description: 'Replace project associations (provide full list)' deleteModels: type: boolean - description: "If true, remove all model associations (even if models array is empty)" + description: 'If true, remove all model associations (even if models array is empty)' deleteProjects: type: boolean - description: "If true, remove all project associations (even if projects array is empty)" + description: 'If true, remove all project associations (even if projects array is empty)' DatasetChangeHistoryEntry: type: object properties: @@ -2259,7 +2280,7 @@ components: type: integer change_type: type: string - description: "e.g. created, deleted, field_change" + description: 'e.g. created, deleted, field_change' field_name: type: string nullable: true @@ -2282,10 +2303,10 @@ components: type: integer key: type: string - description: "Machine-readable trigger identifier" + description: 'Machine-readable trigger identifier' label: type: string - description: "Human-readable name" + description: 'Human-readable name' event_name: type: string description: @@ -2298,17 +2319,17 @@ components: type: integer key: type: string - description: "Machine-readable action identifier" + description: 'Machine-readable action identifier' label: type: string - description: "Human-readable name" + description: 'Human-readable name' description: type: string nullable: true default_params: type: object nullable: true - description: "Default parameters for this action type" + description: 'Default parameters for this action type' Automation: type: object properties: @@ -2320,7 +2341,7 @@ components: type: integer params: type: object - description: "Trigger-specific parameters (JSON)" + description: 'Trigger-specific parameters (JSON)' is_active: type: boolean created_by: @@ -2334,13 +2355,15 @@ components: format: date-time AutomationWithActions: allOf: - - $ref: "#/components/schemas/Automation" - - type: object + - + $ref: '#/components/schemas/Automation' + - + type: object properties: actions: type: array items: - $ref: "#/components/schemas/TenantAutomationAction" + $ref: '#/components/schemas/TenantAutomationAction' TenantAutomationAction: type: object properties: @@ -2353,10 +2376,10 @@ components: params: type: object nullable: true - description: "Action-specific parameters (JSON)" + description: 'Action-specific parameters (JSON)' order: type: integer - description: "Execution order (1-based)" + description: 'Execution order (1-based)' AutomationCreateRequest: type: object required: @@ -2366,14 +2389,14 @@ components: properties: triggerId: type: integer - description: "ID of the automation trigger" + description: 'ID of the automation trigger' name: type: string - description: "Automation name" + description: 'Automation name' params: type: string - description: "JSON-encoded trigger parameters (parsed server-side)" - default: "{}" + description: 'JSON-encoded trigger parameters (parsed server-side)' + default: '{}' actions: type: array minItems: 1 @@ -2384,11 +2407,11 @@ components: properties: action_type_id: type: integer - description: "ID of the action type" + description: 'ID of the action type' params: type: object nullable: true - description: "Action-specific parameters" + description: 'Action-specific parameters' AutomationUpdateRequest: type: object properties: @@ -2398,8 +2421,8 @@ components: type: integer params: type: string - description: "JSON-encoded trigger parameters" - default: "{}" + description: 'JSON-encoded trigger parameters' + default: '{}' is_active: type: boolean actions: @@ -2414,7 +2437,7 @@ components: params: type: object nullable: true - description: "If provided, replaces all existing actions" + description: 'If provided, replaces all existing actions' AutomationHistoryResponse: type: object properties: @@ -2440,17 +2463,17 @@ components: type: array items: type: object - description: "Per-action execution results" + description: 'Per-action execution results' total: type: integer - description: "Total number of log entries" + description: 'Total number of log entries' limit: type: integer offset: type: integer AutomationStats: type: object - description: "Aggregated execution statistics for an automation" + description: 'Aggregated execution statistics for an automation' properties: total_executions: type: integer @@ -2467,7 +2490,7 @@ components: statusCode: type: integer data: - description: "Response payload (varies by endpoint)" + description: 'Response payload (varies by endpoint)' Pagination: type: object properties: @@ -2552,25 +2575,25 @@ components: properties: repository_url: type: string - description: "GitHub repository URL" - example: "https://github.com/owner/repo" + description: 'GitHub repository URL' + example: 'https://github.com/owner/repo' scan_mode: - $ref: "#/components/schemas/ScanMode" + $ref: '#/components/schemas/ScanMode' base_commit_sha: type: string - pattern: "^[0-9a-fA-F]{7,40}$" - description: "Required for incremental scans" + pattern: '^[0-9a-fA-F]{7,40}$' + description: 'Required for incremental scans' head_commit_sha: type: string - pattern: "^[0-9a-fA-F]{7,40}$" - description: "Required for incremental scans" + pattern: '^[0-9a-fA-F]{7,40}$' + description: 'Required for incremental scans' ScanStatusResponse: type: object properties: id: type: integer status: - $ref: "#/components/schemas/ScanStatus" + $ref: '#/components/schemas/ScanStatus' progress: type: number format: float @@ -2610,7 +2633,7 @@ components: repository_name: type: string status: - $ref: "#/components/schemas/ScanStatus" + $ref: '#/components/schemas/ScanStatus' findings_count: type: integer files_scanned: @@ -2630,7 +2653,7 @@ components: type: string nullable: true triggered_by: - $ref: "#/components/schemas/TriggeredByUser" + $ref: '#/components/schemas/TriggeredByUser' risk_score: type: number nullable: true @@ -2645,7 +2668,7 @@ components: format: date-time nullable: true scan_mode: - $ref: "#/components/schemas/ScanMode" + $ref: '#/components/schemas/ScanMode' base_commit_sha: type: string nullable: true @@ -2662,7 +2685,7 @@ components: type: string format: date-time summary: - $ref: "#/components/schemas/ScanSummary" + $ref: '#/components/schemas/ScanSummary' ScanSummary: type: object properties: @@ -2693,7 +2716,7 @@ components: repository_name: type: string status: - $ref: "#/components/schemas/ScanStatus" + $ref: '#/components/schemas/ScanStatus' findings_count: type: integer files_scanned: @@ -2710,7 +2733,7 @@ components: type: integer nullable: true triggered_by: - $ref: "#/components/schemas/TriggeredByUser" + $ref: '#/components/schemas/TriggeredByUser' risk_score: type: number nullable: true @@ -2718,7 +2741,7 @@ components: type: string nullable: true scan_mode: - $ref: "#/components/schemas/ScanMode" + $ref: '#/components/schemas/ScanMode' baseline_scan_id: type: integer nullable: true @@ -2734,9 +2757,9 @@ components: scans: type: array items: - $ref: "#/components/schemas/ScanListItem" + $ref: '#/components/schemas/ScanListItem' pagination: - $ref: "#/components/schemas/Pagination" + $ref: '#/components/schemas/Pagination' CancelScanResponse: type: object properties: @@ -2769,7 +2792,7 @@ components: id: type: integer finding_type: - $ref: "#/components/schemas/FindingType" + $ref: '#/components/schemas/FindingType' category: type: string name: @@ -2777,9 +2800,9 @@ components: provider: type: string confidence: - $ref: "#/components/schemas/ConfidenceLevel" + $ref: '#/components/schemas/ConfidenceLevel' risk_level: - $ref: "#/components/schemas/RiskLevel" + $ref: '#/components/schemas/RiskLevel' description: type: string nullable: true @@ -2791,9 +2814,9 @@ components: file_paths: type: array items: - $ref: "#/components/schemas/FilePath" + $ref: '#/components/schemas/FilePath' governance_status: - $ref: "#/components/schemas/GovernanceStatus" + $ref: '#/components/schemas/GovernanceStatus' governance_updated_at: type: string format: date-time @@ -2808,7 +2831,7 @@ components: type: string nullable: true license_risk: - $ref: "#/components/schemas/LicenseRiskLevel" + $ref: '#/components/schemas/LicenseRiskLevel' license_source: type: string enum: @@ -2828,16 +2851,16 @@ components: type: object nullable: true finding_status: - $ref: "#/components/schemas/FindingStatus" + $ref: '#/components/schemas/FindingStatus' FindingsResponse: type: object properties: findings: type: array items: - $ref: "#/components/schemas/Finding" + $ref: '#/components/schemas/Finding' pagination: - $ref: "#/components/schemas/Pagination" + $ref: '#/components/schemas/Pagination' UpdateGovernanceStatusRequest: type: object properties: @@ -2848,7 +2871,7 @@ components: - approved - flagged nullable: true - description: "Set to null to clear governance status" + description: 'Set to null to clear governance status' UpdateGovernanceStatusResponse: type: object properties: @@ -2901,7 +2924,7 @@ components: type: number minimum: 0 maximum: 1 - description: "All values must sum to 1.0" + description: 'All values must sum to 1.0' VulnerabilityTypesEnabled: type: object properties: @@ -2937,11 +2960,11 @@ components: type: integer nullable: true dimension_weights: - $ref: "#/components/schemas/DimensionWeights" + $ref: '#/components/schemas/DimensionWeights' vulnerability_scan_enabled: type: boolean vulnerability_types_enabled: - $ref: "#/components/schemas/VulnerabilityTypesEnabled" + $ref: '#/components/schemas/VulnerabilityTypesEnabled' updated_by: type: integer nullable: true @@ -2958,11 +2981,11 @@ components: type: integer nullable: true dimension_weights: - $ref: "#/components/schemas/DimensionWeights" + $ref: '#/components/schemas/DimensionWeights' vulnerability_scan_enabled: type: boolean vulnerability_types_enabled: - $ref: "#/components/schemas/VulnerabilityTypesEnabled" + $ref: '#/components/schemas/VulnerabilityTypesEnabled' DependencyGraphResponse: type: object properties: @@ -3095,8 +3118,8 @@ components: properties: repository_url: type: string - description: "GitHub repository URL" - example: "https://github.com/owner/repo" + description: 'GitHub repository URL' + example: 'https://github.com/owner/repo' display_name: type: string nullable: true @@ -3115,17 +3138,17 @@ components: - daily - weekly - monthly - description: "Required when schedule_enabled is true" + description: 'Required when schedule_enabled is true' schedule_day_of_week: type: integer minimum: 0 maximum: 6 - description: "Required for weekly schedule (0=Sunday)" + description: 'Required for weekly schedule (0=Sunday)' schedule_day_of_month: type: integer minimum: 1 maximum: 31 - description: "Required for monthly schedule" + description: 'Required for monthly schedule' schedule_hour: type: integer minimum: 0 @@ -3189,12 +3212,12 @@ components: repositories: type: array items: - $ref: "#/components/schemas/Repository" + $ref: '#/components/schemas/Repository' pagination: - $ref: "#/components/schemas/Pagination" + $ref: '#/components/schemas/Pagination' AITrustCentreOverview: type: object - description: "Full overview with all sections" + description: 'Full overview with all sections' properties: intro: type: object @@ -3354,7 +3377,7 @@ components: type: string AITrustCentrePublicPage: type: object - description: "Conditionally includes sections based on visibility settings" + description: 'Conditionally includes sections based on visibility settings' properties: info: type: object @@ -3461,18 +3484,18 @@ components: type: string enum: - Malfunction - - "Unexpected behavior" - - "Model drift" + - 'Unexpected behavior' + - 'Model drift' - Misuse - - "Data corruption" - - "Security breach" - - "Performance degradation" + - 'Data corruption' + - 'Security breach' + - 'Performance degradation' IncidentSeverity: type: string enum: - Minor - Serious - - "Very serious" + - 'Very serious' IncidentStatus: type: string enum: @@ -3486,7 +3509,7 @@ components: - Approved - Rejected - Pending - - "Not required" + - 'Not required' Incident: type: object properties: @@ -3498,11 +3521,11 @@ components: ai_project: type: string type: - $ref: "#/components/schemas/IncidentType" + $ref: '#/components/schemas/IncidentType' severity: - $ref: "#/components/schemas/IncidentSeverity" + $ref: '#/components/schemas/IncidentSeverity' status: - $ref: "#/components/schemas/IncidentStatus" + $ref: '#/components/schemas/IncidentStatus' occurred_date: type: string format: date-time @@ -3537,7 +3560,7 @@ components: archived: type: boolean approval_status: - $ref: "#/components/schemas/IncidentApprovalStatus" + $ref: '#/components/schemas/IncidentApprovalStatus' approved_by: type: string nullable: true @@ -3572,11 +3595,11 @@ components: ai_project: type: string type: - $ref: "#/components/schemas/IncidentType" + $ref: '#/components/schemas/IncidentType' severity: - $ref: "#/components/schemas/IncidentSeverity" + $ref: '#/components/schemas/IncidentSeverity' status: - $ref: "#/components/schemas/IncidentStatus" + $ref: '#/components/schemas/IncidentStatus' occurred_date: type: string format: date-time @@ -3586,16 +3609,18 @@ components: reporter: type: string approval_status: - $ref: "#/components/schemas/IncidentApprovalStatus" + $ref: '#/components/schemas/IncidentApprovalStatus' approved_by: type: string categories_of_harm: oneOf: - - type: array + - + type: array items: type: string - - type: string - description: "Comma-separated string (will be split)" + - + type: string + description: 'Comma-separated string (will be split)' affected_persons_groups: type: string description: @@ -3621,16 +3646,16 @@ components: type: string UpdateIncidentRequest: type: object - description: "All fields are optional; only provided fields are updated." + description: 'All fields are optional; only provided fields are updated.' properties: ai_project: type: string type: - $ref: "#/components/schemas/IncidentType" + $ref: '#/components/schemas/IncidentType' severity: - $ref: "#/components/schemas/IncidentSeverity" + $ref: '#/components/schemas/IncidentSeverity' status: - $ref: "#/components/schemas/IncidentStatus" + $ref: '#/components/schemas/IncidentStatus' occurred_date: type: string format: date-time @@ -3640,15 +3665,17 @@ components: reporter: type: string approval_status: - $ref: "#/components/schemas/IncidentApprovalStatus" + $ref: '#/components/schemas/IncidentApprovalStatus' approved_by: type: string categories_of_harm: oneOf: - - type: array + - + type: array items: type: string - - type: string + - + type: string affected_persons_groups: type: string description: @@ -3702,7 +3729,7 @@ components: subClauses: type: array items: - $ref: "#/components/schemas/ISO27001SubClause" + $ref: '#/components/schemas/ISO27001SubClause' ISO27001SubClause: type: object properties: @@ -3717,9 +3744,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -3770,7 +3797,7 @@ components: controls: type: array items: - $ref: "#/components/schemas/ISO27001AnnexControl" + $ref: '#/components/schemas/ISO27001AnnexControl' ISO27001AnnexControl: type: object properties: @@ -3785,9 +3812,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -3818,16 +3845,16 @@ components: properties: user_id: type: string - description: "User ID for file upload attribution" + description: 'User ID for file upload attribution' project_id: type: string - description: "Project ID for file upload association" + description: 'Project ID for file upload association' status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -3842,37 +3869,37 @@ components: type: string tags: type: string - description: "JSON-encoded array of tag strings" + description: 'JSON-encoded array of tag strings' delete: type: string - description: "JSON-encoded array of file IDs to unlink" + description: 'JSON-encoded array of file IDs to unlink' risksDelete: type: string - description: "JSON-encoded array of risk IDs to remove" + description: 'JSON-encoded array of risk IDs to remove' risksMitigated: type: string - description: "JSON-encoded array of risk IDs to add" + description: 'JSON-encoded array of risk IDs to add' files: type: array items: type: string format: binary - description: "Evidence files to upload" + description: 'Evidence files to upload' ISO27001SaveAnnexRequest: type: object properties: user_id: type: string - description: "User ID for file upload attribution" + description: 'User ID for file upload attribution' project_id: type: string - description: "Project ID for file upload association" + description: 'Project ID for file upload association' status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -3887,22 +3914,22 @@ components: type: string tags: type: string - description: "JSON-encoded array of tag strings" + description: 'JSON-encoded array of tag strings' delete: type: string - description: "JSON-encoded array of file IDs to unlink" + description: 'JSON-encoded array of file IDs to unlink' risksDelete: type: string - description: "JSON-encoded array of risk IDs to remove" + description: 'JSON-encoded array of risk IDs to remove' risksMitigated: type: string - description: "JSON-encoded array of risk IDs to add" + description: 'JSON-encoded array of risk IDs to add' files: type: array items: type: string format: binary - description: "Evidence files to upload" + description: 'Evidence files to upload' ISO42001Clause: type: object properties: @@ -3924,7 +3951,7 @@ components: subClauses: type: array items: - $ref: "#/components/schemas/ISO42001SubClause" + $ref: '#/components/schemas/ISO42001SubClause' ISO42001SubClause: type: object properties: @@ -3939,9 +3966,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -3988,7 +4015,7 @@ components: categories: type: array items: - $ref: "#/components/schemas/ISO42001AnnexCategory" + $ref: '#/components/schemas/ISO42001AnnexCategory' ISO42001AnnexCategory: type: object properties: @@ -4003,9 +4030,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -4041,9 +4068,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -4058,16 +4085,16 @@ components: type: string tags: type: string - description: "JSON-encoded array of tag strings" + description: 'JSON-encoded array of tag strings' delete: type: string - description: "JSON-encoded array of file IDs to unlink" + description: 'JSON-encoded array of file IDs to unlink' risksDelete: type: string - description: "JSON-encoded array of risk IDs to remove" + description: 'JSON-encoded array of risk IDs to remove' risksMitigated: type: string - description: "JSON-encoded array of risk IDs to add" + description: 'JSON-encoded array of risk IDs to add' files: type: array items: @@ -4083,9 +4110,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -4100,16 +4127,16 @@ components: type: string tags: type: string - description: "JSON-encoded array of tag strings" + description: 'JSON-encoded array of tag strings' delete: type: string - description: "JSON-encoded array of file IDs to unlink" + description: 'JSON-encoded array of file IDs to unlink' risksDelete: type: string - description: "JSON-encoded array of risk IDs to remove" + description: 'JSON-encoded array of risk IDs to remove' risksMitigated: type: string - description: "JSON-encoded array of risk IDs to add" + description: 'JSON-encoded array of risk IDs to add' files: type: array items: @@ -4152,9 +4179,9 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -4185,16 +4212,16 @@ components: properties: user_id: type: string - description: "User ID for file upload attribution" + description: 'User ID for file upload attribution' project_id: type: string - description: "Project ID for file upload association" + description: 'Project ID for file upload association' status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done owner: type: integer @@ -4209,22 +4236,22 @@ components: type: string tags: type: string - description: "JSON-encoded array of tag strings" + description: 'JSON-encoded array of tag strings' delete: type: string - description: "JSON-encoded array of file IDs to unlink" + description: 'JSON-encoded array of file IDs to unlink' risksDelete: type: string - description: "JSON-encoded array of risk IDs to remove" + description: 'JSON-encoded array of risk IDs to remove' risksMitigated: type: string - description: "JSON-encoded array of risk IDs to add" + description: 'JSON-encoded array of risk IDs to add' files: type: array items: type: string format: binary - description: "Evidence files to upload" + description: 'Evidence files to upload' NISTSubcategoryStatusUpdate: type: object required: @@ -4233,11 +4260,11 @@ components: status: type: string enum: - - "Not started" + - 'Not started' - Draft - - "In review" + - 'In review' - Done - description: "New status value" + description: 'New status value' NISTProgress: type: object properties: @@ -4268,17 +4295,17 @@ components: type: object properties: riskManagement: - $ref: "#/components/schemas/ModuleScore" + $ref: '#/components/schemas/ModuleScore' vendorManagement: - $ref: "#/components/schemas/ModuleScore" + $ref: '#/components/schemas/ModuleScore' projectGovernance: - $ref: "#/components/schemas/ModuleScore" + $ref: '#/components/schemas/ModuleScore' modelLifecycle: - $ref: "#/components/schemas/ModuleScore" + $ref: '#/components/schemas/ModuleScore' policyDocumentation: - $ref: "#/components/schemas/ModuleScore" + $ref: '#/components/schemas/ModuleScore' metadata: - $ref: "#/components/schemas/ComplianceMetadata" + $ref: '#/components/schemas/ComplianceMetadata' ModuleScore: type: object properties: @@ -4288,18 +4315,18 @@ components: maximum: 100 weight: type: number - description: "Module weight (sums to 1.0 across all modules)" + description: 'Module weight (sums to 1.0 across all modules)' components: type: array items: - $ref: "#/components/schemas/ComponentScore" + $ref: '#/components/schemas/ComponentScore' totalDataPoints: type: integer qualityScore: type: number minimum: 0 maximum: 1 - description: "Data completeness indicator" + description: 'Data completeness indicator' ComponentScore: type: object properties: @@ -4313,7 +4340,7 @@ components: type: integer details: type: object - description: "Module-specific details" + description: 'Module-specific details' ComplianceMetadata: type: object properties: @@ -4350,44 +4377,29 @@ components: type: string ComplianceDetails: allOf: - - $ref: "#/components/schemas/ComplianceScore" - - type: object + - + $ref: '#/components/schemas/ComplianceScore' + - + type: object properties: insights: type: object properties: strongestModule: type: object - properties: { name: { type: string }, score: { type: number } } + properties: {name: {type: string}, score: {type: number}} weakestModule: type: object - properties: { name: { type: string }, score: { type: number } } + properties: {name: {type: string}, score: {type: number}} improvementPriority: type: array - items: - { - type: object, - properties: - { - module: { type: string }, - score: { type: number }, - weight: { type: number }, - impact: { type: number, description: "(100 - score) * weight" }, - }, - } + items: {type: object, properties: {module: {type: string}, score: {type: number}, weight: {type: number}, impact: {type: number, description: '(100 - score) * weight'}}} overallTrend: type: string enum: [up, down, stable] dataQuality: type: object - properties: - { - riskManagement: { type: number }, - vendorManagement: { type: number }, - projectGovernance: { type: number }, - modelLifecycle: { type: number }, - policyDocumentation: { type: number }, - } + properties: {riskManagement: {type: number}, vendorManagement: {type: number}, projectGovernance: {type: number}, modelLifecycle: {type: number}, policyDocumentation: {type: number}} AssignmentResponse: type: object properties: @@ -4403,7 +4415,7 @@ components: data: type: array items: - $ref: "#/components/schemas/Risk" + $ref: '#/components/schemas/Risk' Risk: type: object properties: @@ -4425,7 +4437,7 @@ components: code: type: integer data: - description: "Response payload" + description: 'Response payload' ShareLinkSettings: type: object properties: @@ -4458,9 +4470,9 @@ components: resource_id: type: integer minimum: 0 - description: "Use 0 for sharing the entire table/list view" + description: 'Use 0 for sharing the entire table/list view' settings: - $ref: "#/components/schemas/ShareLinkSettings" + $ref: '#/components/schemas/ShareLinkSettings' expires_at: type: string format: date-time @@ -4469,7 +4481,7 @@ components: type: object properties: settings: - $ref: "#/components/schemas/ShareLinkSettings" + $ref: '#/components/schemas/ShareLinkSettings' is_enabled: type: boolean expires_at: @@ -4488,7 +4500,7 @@ components: resource_id: type: integer settings: - $ref: "#/components/schemas/ShareLinkSettings" + $ref: '#/components/schemas/ShareLinkSettings' is_enabled: type: boolean expires_at: @@ -4506,11 +4518,13 @@ components: format: uri ShareLinkListItem: allOf: - - $ref: "#/components/schemas/ShareLinkResponse" - - properties: + - + $ref: '#/components/schemas/ShareLinkResponse' + - + properties: is_valid: type: boolean - description: "Whether the link is currently active and not expired" + description: 'Whether the link is currently active and not expired' ShareLinkMetadata: type: object properties: @@ -4523,7 +4537,7 @@ components: resource_id: type: integer settings: - $ref: "#/components/schemas/ShareLinkSettings" + $ref: '#/components/schemas/ShareLinkSettings' is_enabled: type: boolean expires_at: @@ -4547,12 +4561,14 @@ components: resource_type: type: string settings: - $ref: "#/components/schemas/ShareLinkSettings" + $ref: '#/components/schemas/ShareLinkSettings' data: - description: "Resource data (object for single record, array for table view)" + description: 'Resource data (object for single record, array for table view)' oneOf: - - type: object - - type: array + - + type: object + - + type: array items: type: object permissions: @@ -4610,19 +4626,19 @@ components: properties: results: type: object - description: "Results grouped by entity type (projects, vendors, models, etc.)" + description: 'Results grouped by entity type (projects, vendors, models, etc.)' additionalProperties: type: array items: type: object - description: "Entity-specific result object" + description: 'Entity-specific result object' totalCount: type: integer query: type: string message: type: string - description: "Present when query is too short" + description: 'Present when query is too short' ReportGenerateRequest: type: object required: @@ -4639,7 +4655,8 @@ components: type: integer reportType: oneOf: - - type: string + - + type: string enum: - projectRisks - vendorRisks @@ -4654,7 +4671,8 @@ components: - policyManager - incidentManagement - all - - type: array + - + type: array items: type: string reportName: @@ -4670,7 +4688,7 @@ components: default: false llmKeyId: type: integer - description: "LLM key ID for AI-enhanced reports" + description: 'LLM key ID for AI-enhanced reports' GeneratedReport: type: object properties: @@ -4694,16 +4712,16 @@ components: properties: projects: type: integer - description: "Total project count" + description: 'Total project count' trainings: type: integer - description: "Total training records" + description: 'Total training records' models: type: integer - description: "Total model count" + description: 'Total model count' reports: type: integer - description: "Total report count" + description: 'Total report count' task_radar: type: object properties: @@ -4717,7 +4735,7 @@ components: type: array items: type: object - description: "Project summary objects" + description: 'Project summary objects' ConformityStep: type: object properties: @@ -4731,10 +4749,10 @@ components: status: type: string enum: - - "Not started" - - "In progress" + - 'Not started' + - 'In progress' - Completed - - "Not needed" + - 'Not needed' owner: type: string nullable: true @@ -4770,7 +4788,7 @@ components: conformitySteps: type: array items: - $ref: "#/components/schemas/ConformityStep" + $ref: '#/components/schemas/ConformityStep' completedStepsCount: type: integer totalStepsCount: @@ -4883,10 +4901,10 @@ components: status: type: string enum: - - "Not started" - - "In progress" + - 'Not started' + - 'In progress' - Completed - - "Not needed" + - 'Not needed' owner: type: string dueDate: @@ -4988,7 +5006,7 @@ components: format: date-time TierFeatures: type: object - description: "Tier details with associated feature flags" + description: 'Tier details with associated feature flags' properties: id: type: integer @@ -5013,11 +5031,11 @@ components: properties: name: type: string - description: "Descriptive name for the token" + description: 'Descriptive name for the token' expires_in_days: type: integer minimum: 1 - description: "Number of days until token expires" + description: 'Number of days until token expires' ApiToken: type: object properties: @@ -5037,11 +5055,13 @@ components: format: date-time ApiTokenCreated: allOf: - - $ref: "#/components/schemas/ApiToken" - - properties: + - + $ref: '#/components/schemas/ApiToken' + - + properties: token: type: string - description: "Full JWT token value (only shown on creation)" + description: 'Full JWT token value (only shown on creation)' LLMKeyCreateRequest: type: object required: @@ -5055,23 +5075,23 @@ components: - OpenAI - OpenRouter - Custom - description: "LLM provider name" + description: 'LLM provider name' key: type: string - description: "API key value" + description: 'API key value' model: type: string - description: "Default model to use with this key" + description: 'Default model to use with this key' url: type: string format: uri - description: "Required for Custom provider; auto-populated for others" + description: 'Required for Custom provider; auto-populated for others' custom_headers: type: object additionalProperties: type: string nullable: true - description: "Optional custom headers (string key-value pairs)" + description: 'Optional custom headers (string key-value pairs)' LLMKeyUpdateRequest: type: object properties: @@ -5103,7 +5123,7 @@ components: type: string key: type: string - description: "Masked key value" + description: 'Masked key value' url: type: string model: @@ -5144,7 +5164,7 @@ components: minimum: 1 date_format: type: string - description: "Preferred date format (e.g., YYYY-MM-DD, DD/MM/YYYY)" + description: 'Preferred date format (e.g., YYYY-MM-DD, DD/MM/YYYY)' UserPreferenceUpdateRequest: type: object properties: @@ -5201,9 +5221,9 @@ components: files: type: array items: - $ref: "#/components/schemas/FileListItem" + $ref: '#/components/schemas/FileListItem' pagination: - $ref: "#/components/schemas/Pagination" + $ref: '#/components/schemas/Pagination' FileListItem: type: object properties: @@ -5245,11 +5265,11 @@ components: type: string snippet: type: string - description: "Highlighted text snippet matching the query" + description: 'Highlighted text snippet matching the query' rank: type: number pagination: - $ref: "#/components/schemas/Pagination" + $ref: '#/components/schemas/Pagination' FileMetadata: type: object properties: @@ -5284,7 +5304,7 @@ components: items: type: string maxItems: 50 - description: "Each tag max 100 chars, alphanumeric/spaces/hyphens/underscores only" + description: 'Each tag max 100 chars, alphanumeric/spaces/hyphens/underscores only' review_status: type: string enum: @@ -5357,13 +5377,13 @@ components: parent_id: type: integer nullable: true - description: "Parent folder ID (null for root)" + description: 'Parent folder ID (null for root)' color: type: string - description: "Hex color code" + description: 'Hex color code' icon: type: string - description: "Icon identifier" + description: 'Icon identifier' UpdateFolderRequest: type: object properties: @@ -5375,7 +5395,7 @@ components: parent_id: type: integer nullable: true - description: "New parent (null to move to root). Cannot create circular refs." + description: 'New parent (null to move to root). Cannot create circular refs.' color: type: string icon: @@ -5453,7 +5473,7 @@ components: type: integer key: type: string - description: "Full API key (shown only on creation)" + description: 'Full API key (shown only on creation)' key_prefix: type: string label: @@ -5520,7 +5540,7 @@ components: domain: type: string status: - $ref: "#/components/schemas/ShadowAiToolStatus" + $ref: '#/components/schemas/ShadowAiToolStatus' first_seen: type: string format: date-time @@ -5976,12 +5996,12 @@ components: - Low - Medium - High - description: "Task priority level." + description: 'Task priority level.' TaskStatus: type: string enum: - Open - - "In Progress" + - 'In Progress' - Completed - Overdue - Deleted @@ -5999,7 +6019,7 @@ components: - iso27001_annexcontrol - eu_control - eu_subcontrol - description: "Type of entity that can be linked to a task." + description: 'Type of entity that can be linked to a task.' CreateTaskRequest: type: object required: @@ -6007,7 +6027,7 @@ components: properties: title: type: string - example: "Review vendor risk assessment" + example: 'Review vendor risk assessment' description: type: string nullable: true @@ -6015,11 +6035,11 @@ components: type: string format: date-time nullable: true - example: "2026-05-15T00:00:00.000Z" + example: '2026-05-15T00:00:00.000Z' priority: - $ref: "#/components/schemas/TaskPriority" + $ref: '#/components/schemas/TaskPriority' status: - $ref: "#/components/schemas/TaskStatus" + $ref: '#/components/schemas/TaskStatus' categories: type: array items: @@ -6031,10 +6051,12 @@ components: type: array items: oneOf: - - type: integer - - type: object + - + type: integer + - + type: object properties: - user_id: { type: integer } + user_id: {type: integer} required: - user_id example: @@ -6049,7 +6071,7 @@ components: entity_id: type: integer entity_type: - $ref: "#/components/schemas/EntityType" + $ref: '#/components/schemas/EntityType' entity_name: type: string UpdateTaskRequest: @@ -6065,9 +6087,9 @@ components: format: date-time nullable: true priority: - $ref: "#/components/schemas/TaskPriority" + $ref: '#/components/schemas/TaskPriority' status: - $ref: "#/components/schemas/TaskStatus" + $ref: '#/components/schemas/TaskStatus' categories: type: array items: @@ -6084,7 +6106,7 @@ components: entity_id: type: integer entity_type: - $ref: "#/components/schemas/EntityType" + $ref: '#/components/schemas/EntityType' entity_name: type: string AddEntityLinkRequest: @@ -6097,10 +6119,10 @@ components: type: integer example: 42 entity_type: - $ref: "#/components/schemas/EntityType" + $ref: '#/components/schemas/EntityType' entity_name: type: string - example: "Acme Corp" + example: 'Acme Corp' Task: type: object properties: @@ -6109,7 +6131,7 @@ components: example: 1 title: type: string - example: "Review vendor risk assessment" + example: 'Review vendor risk assessment' description: type: string nullable: true @@ -6122,9 +6144,9 @@ components: format: date-time nullable: true priority: - $ref: "#/components/schemas/TaskPriority" + $ref: '#/components/schemas/TaskPriority' status: - $ref: "#/components/schemas/TaskStatus" + $ref: '#/components/schemas/TaskStatus' categories: type: array items: @@ -6139,8 +6161,10 @@ components: format: date-time TaskWithAssignees: allOf: - - $ref: "#/components/schemas/Task" - - type: object + - + $ref: '#/components/schemas/Task' + - + type: object properties: assignees: type: array @@ -6148,8 +6172,10 @@ components: type: integer TaskWithRelations: allOf: - - $ref: "#/components/schemas/Task" - - type: object + - + $ref: '#/components/schemas/Task' + - + type: object properties: assignees: type: array @@ -6158,11 +6184,13 @@ components: entity_links: type: array items: - $ref: "#/components/schemas/EntityLinkSummary" + $ref: '#/components/schemas/EntityLinkSummary' TaskDetail: allOf: - - $ref: "#/components/schemas/Task" - - type: object + - + $ref: '#/components/schemas/Task' + - + type: object properties: assignees: type: array @@ -6170,18 +6198,18 @@ components: type: integer creator_name: type: string - example: "Jane Smith" + example: 'Jane Smith' assignee_names: type: array items: type: string example: - - "John Doe" - - "Alice Johnson" + - 'John Doe' + - 'Alice Johnson' entity_links: type: array items: - $ref: "#/components/schemas/EntityLinkSummary" + $ref: '#/components/schemas/EntityLinkSummary' EntityLinkSummary: type: object properties: @@ -6190,7 +6218,7 @@ components: entity_id: type: integer entity_type: - $ref: "#/components/schemas/EntityType" + $ref: '#/components/schemas/EntityType' entity_name: type: string TaskEntityLink: @@ -6203,7 +6231,7 @@ components: entity_id: type: integer entity_type: - $ref: "#/components/schemas/EntityType" + $ref: '#/components/schemas/EntityType' entity_name: type: string nullable: true @@ -6222,41 +6250,47 @@ components: - message EnvelopeEmpty: allOf: - - $ref: "#/components/schemas/EnvelopeBase" - - type: object + - + $ref: '#/components/schemas/EnvelopeBase' + - + type: object properties: message: - example: "No Content" + example: 'No Content' data: type: array items: {} example: [] EnvelopeNotFound: allOf: - - $ref: "#/components/schemas/EnvelopeBase" - - type: object + - + $ref: '#/components/schemas/EnvelopeBase' + - + type: object properties: message: - example: "Not Found" + example: 'Not Found' data: nullable: true example: null EnvelopeBadRequest: allOf: - - $ref: "#/components/schemas/EnvelopeBase" - - type: object + - + $ref: '#/components/schemas/EnvelopeBase' + - + type: object properties: message: - example: "Bad Request" + example: 'Bad Request' data: type: string - example: "Invalid training ID" + example: 'Invalid training ID' EnvelopeError: type: object properties: message: type: string - example: "Internal Server Error" + example: 'Internal Server Error' error: type: string required: @@ -6270,10 +6304,10 @@ components: example: 42 training_name: type: string - example: "AI Governance Fundamentals" + example: 'AI Governance Fundamentals' duration: type: string - example: "2 hours" + example: '2 hours' provider: type: string example: Internal @@ -6284,7 +6318,7 @@ components: type: string enum: - Planned - - "In Progress" + - 'In Progress' - Completed example: Planned numberOfPeople: @@ -6292,7 +6326,7 @@ components: example: 25 description: type: string - example: "Introductory course on EU AI Act compliance" + example: 'Introductory course on EU AI Act compliance' progressPercentage: type: integer enum: @@ -6328,10 +6362,10 @@ components: properties: training_name: type: string - example: "AI Governance Fundamentals" + example: 'AI Governance Fundamentals' duration: type: string - example: "2 hours" + example: '2 hours' provider: type: string example: Internal @@ -6342,7 +6376,7 @@ components: type: string enum: - Planned - - "In Progress" + - 'In Progress' - Completed example: Planned numberOfPeople: @@ -6350,7 +6384,7 @@ components: example: 25 description: type: string - example: "Introductory course on EU AI Act compliance" + example: 'Introductory course on EU AI Act compliance' is_demo: type: boolean default: false @@ -6359,10 +6393,10 @@ components: properties: training_name: type: string - example: "Advanced AI Risk Management" + example: 'Advanced AI Risk Management' duration: type: string - example: "3 days" + example: '3 days' provider: type: string example: External @@ -6373,35 +6407,39 @@ components: type: string enum: - Planned - - "In Progress" + - 'In Progress' - Completed - example: "In Progress" + example: 'In Progress' numberOfPeople: type: integer example: 30 description: type: string - example: "Updated scope to cover ISO 42001" + example: 'Updated scope to cover ISO 42001' TrainingListResponse: allOf: - - $ref: "#/components/schemas/EnvelopeBase" - - type: object + - + $ref: '#/components/schemas/EnvelopeBase' + - + type: object properties: message: example: OK data: type: array items: - $ref: "#/components/schemas/Training" + $ref: '#/components/schemas/Training' TrainingSingleResponse: allOf: - - $ref: "#/components/schemas/EnvelopeBase" - - type: object + - + $ref: '#/components/schemas/EnvelopeBase' + - + type: object properties: message: example: OK data: - $ref: "#/components/schemas/Training" + $ref: '#/components/schemas/Training' ChangeHistoryEntry: type: object properties: @@ -6424,7 +6462,7 @@ components: new_value: type: string nullable: true - example: "In Progress" + example: 'In Progress' change_type: type: string enum: @@ -6457,7 +6495,7 @@ components: data: type: array items: - $ref: "#/components/schemas/ChangeHistoryEntry" + $ref: '#/components/schemas/ChangeHistoryEntry' hasMore: type: boolean example: false @@ -6466,13 +6504,15 @@ components: example: 5 ChangeHistoryResponse: allOf: - - $ref: "#/components/schemas/EnvelopeBase" - - type: object + - + $ref: '#/components/schemas/EnvelopeBase' + - + type: object properties: message: example: OK data: - $ref: "#/components/schemas/ChangeHistoryData" + $ref: '#/components/schemas/ChangeHistoryData' CreateOrganizationRequest: type: object required: @@ -6484,12 +6524,12 @@ components: properties: name: type: string - example: "Acme Corp" + example: 'Acme Corp' logo: type: string format: uri nullable: true - example: "https://example.com/logo.png" + example: 'https://example.com/logo.png' userEmail: type: string format: email @@ -6509,12 +6549,12 @@ components: properties: name: type: string - example: "Acme Corporation" + example: 'Acme Corporation' logo: type: string format: uri nullable: true - example: "https://example.com/new-logo.png" + example: 'https://example.com/new-logo.png' Organization: type: object properties: @@ -6523,11 +6563,11 @@ components: example: 1 name: type: string - example: "Acme Corp" + example: 'Acme Corp' logo: type: string nullable: true - example: "https://example.com/logo.png" + example: 'https://example.com/logo.png' created_at: type: string format: date-time @@ -6563,7 +6603,7 @@ components: type: object properties: user: - $ref: "#/components/schemas/SafeUser" + $ref: '#/components/schemas/SafeUser' organization: type: object properties: @@ -6572,7 +6612,7 @@ components: example: 1 name: type: string - example: "Acme Corp" + example: 'Acme Corp' token: type: string example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... @@ -6675,16 +6715,17 @@ components: type: integer example: 7 type: - $ref: "#/components/schemas/NotificationType" + $ref: '#/components/schemas/NotificationType' title: type: string - example: "Task assigned to you" + example: 'Task assigned to you' message: type: string - example: "You have been assigned to task 'Review vendor contract'." + example: 'You have been assigned to task ''Review vendor contract''.' entity_type: allOf: - - $ref: "#/components/schemas/NotificationEntityType" + - + $ref: '#/components/schemas/NotificationEntityType' nullable: true entity_id: type: integer @@ -6693,7 +6734,7 @@ components: entity_name: type: string nullable: true - example: "Review vendor contract" + example: 'Review vendor contract' action_url: type: string nullable: true @@ -6708,7 +6749,7 @@ components: created_at: type: string format: date-time - example: "2026-04-20T10:00:00.000Z" + example: '2026-04-20T10:00:00.000Z' created_by: type: integer nullable: true @@ -6734,7 +6775,7 @@ components: type: array maxItems: 10 items: - $ref: "#/components/schemas/NotificationJSON" + $ref: '#/components/schemas/NotificationJSON' RealtimeNotification: type: object required: @@ -6746,7 +6787,7 @@ components: enum: - notification data: - $ref: "#/components/schemas/NotificationJSON" + $ref: '#/components/schemas/NotificationJSON' ApiEnvelope: type: object properties: @@ -6754,7 +6795,7 @@ components: type: integer example: 200 data: - description: "Response payload (varies per endpoint)" + description: 'Response payload (varies per endpoint)' FriaErrorEnvelope: type: object properties: @@ -6763,7 +6804,7 @@ components: example: 400 data: type: string - example: "Invalid project ID" + example: 'Invalid project ID' DeletedResponse: type: object properties: @@ -6807,7 +6848,7 @@ components: version: type: integer status: - $ref: "#/components/schemas/FriaStatus" + $ref: '#/components/schemas/FriaStatus' assessment_owner: type: string nullable: true @@ -6896,7 +6937,7 @@ components: risk_score: type: integer risk_level: - $ref: "#/components/schemas/FriaRiskLevel" + $ref: '#/components/schemas/FriaRiskLevel' rights_flagged: type: integer created_by: @@ -6927,7 +6968,7 @@ components: type: object properties: status: - $ref: "#/components/schemas/FriaStatus" + $ref: '#/components/schemas/FriaStatus' assessment_owner: type: string assessment_date: @@ -6988,19 +7029,19 @@ components: type: object properties: assessment: - $ref: "#/components/schemas/FriaAssessment" + $ref: '#/components/schemas/FriaAssessment' rights: type: array items: - $ref: "#/components/schemas/FriaRight" + $ref: '#/components/schemas/FriaRight' riskItems: type: array items: - $ref: "#/components/schemas/FriaRiskItem" + $ref: '#/components/schemas/FriaRiskItem' modelLinks: type: array items: - $ref: "#/components/schemas/FriaModelLink" + $ref: '#/components/schemas/FriaModelLink' FriaRight: type: object properties: @@ -7064,9 +7105,9 @@ components: risk_description: type: string likelihood: - $ref: "#/components/schemas/FriaLikelihood" + $ref: '#/components/schemas/FriaLikelihood' severity: - $ref: "#/components/schemas/FriaSeverity" + $ref: '#/components/schemas/FriaSeverity' existing_controls: type: string nullable: true @@ -7099,9 +7140,9 @@ components: risk_description: type: string likelihood: - $ref: "#/components/schemas/FriaLikelihood" + $ref: '#/components/schemas/FriaLikelihood' severity: - $ref: "#/components/schemas/FriaSeverity" + $ref: '#/components/schemas/FriaSeverity' existing_controls: type: string further_action: @@ -7116,9 +7157,9 @@ components: risk_description: type: string likelihood: - $ref: "#/components/schemas/FriaLikelihood" + $ref: '#/components/schemas/FriaLikelihood' severity: - $ref: "#/components/schemas/FriaSeverity" + $ref: '#/components/schemas/FriaSeverity' existing_controls: type: string further_action: @@ -7175,19 +7216,19 @@ components: type: object properties: assessment: - $ref: "#/components/schemas/FriaAssessment" + $ref: '#/components/schemas/FriaAssessment' rights: type: array items: - $ref: "#/components/schemas/FriaRight" + $ref: '#/components/schemas/FriaRight' riskItems: type: array items: - $ref: "#/components/schemas/FriaRiskItem" + $ref: '#/components/schemas/FriaRiskItem' modelLinks: type: array items: - $ref: "#/components/schemas/FriaModelLink" + $ref: '#/components/schemas/FriaModelLink' snapshot_reason: type: string nullable: true @@ -7210,7 +7251,7 @@ components: message: type: string data: - description: "Response payload (present on 1xx-4xx)" + description: 'Response payload (present on 1xx-4xx)' error: type: string ErrorResponse400: @@ -7218,10 +7259,10 @@ components: properties: message: type: string - example: "Bad Request" + example: 'Bad Request' data: type: string - example: "userId query parameter is required" + example: 'userId query parameter is required' ErrorResponse401: type: object properties: @@ -7243,7 +7284,7 @@ components: properties: message: type: string - example: "Not Found" + example: 'Not Found' data: type: string ErrorResponse500: @@ -7251,17 +7292,17 @@ components: properties: message: type: string - example: "Internal Server Error" + example: 'Internal Server Error' error: type: string SlackNotificationRoutingType: type: string enum: - - "Membership and roles" - - "Projects and organizations" - - "Policy reminders and status" - - "Evidence and task alerts" - - "Control or policy changes" + - 'Membership and roles' + - 'Projects and organizations' + - 'Policy reminders and status' + - 'Evidence and task alerts' + - 'Control or policy changes' SlackWebhookFull: type: object properties: @@ -7274,19 +7315,19 @@ components: type: string scope: type: string - example: "incoming-webhook,chat:write" + example: 'incoming-webhook,chat:write' user_id: type: integer example: 5 team_name: type: string - example: "Acme Corp" + example: 'Acme Corp' team_id: type: string example: T01234ABC channel: type: string - example: "#general" + example: '#general' channel_id: type: string example: C01234ABC @@ -7303,7 +7344,7 @@ components: routing_type: type: array items: - $ref: "#/components/schemas/SlackNotificationRoutingType" + $ref: '#/components/schemas/SlackNotificationRoutingType' nullable: true created_at: type: string @@ -7336,7 +7377,7 @@ components: routing_type: type: array items: - $ref: "#/components/schemas/SlackNotificationRoutingType" + $ref: '#/components/schemas/SlackNotificationRoutingType' nullable: true CreateSlackWebhookRequest: type: object @@ -7359,7 +7400,7 @@ components: routing_type: type: array items: - $ref: "#/components/schemas/SlackNotificationRoutingType" + $ref: '#/components/schemas/SlackNotificationRoutingType' SendSlackMessageRequest: type: object required: @@ -7368,10 +7409,10 @@ components: properties: title: type: string - example: "New policy update" + example: 'New policy update' message: type: string - example: "Policy *Data Retention* has been updated." + example: 'Policy *Data Retention* has been updated.' SlackMessageSentResult: type: object properties: @@ -7380,7 +7421,7 @@ components: example: true messageId: type: string - example: "1234567890.123456" + example: '1234567890.123456' channel: type: string example: C01234ABC @@ -7392,7 +7433,7 @@ components: example: true token_name: type: string - example: "GitHub Personal Access Token" + example: 'GitHub Personal Access Token' last_used_at: type: string format: date-time @@ -7410,8 +7451,8 @@ components: example: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx token_name: type: string - default: "GitHub Personal Access Token" - example: "CI/CD Scanner Token" + default: 'GitHub Personal Access Token' + example: 'CI/CD Scanner Token' TestGitHubTokenRequest: type: object required: @@ -7432,7 +7473,7 @@ components: type: string example: - repo - - "read:org" + - 'read:org' rate_limit: type: object properties: @@ -7447,7 +7488,7 @@ components: format: date-time error: type: string - example: "Invalid or expired token" + example: 'Invalid or expired token' GitHubWebhookPayload: type: object required: @@ -7485,7 +7526,7 @@ components: type: boolean reason: type: string - example: "Scan triggered for push to main" + example: 'Scan triggered for push to main' GitHubWebhookPong: type: object properties: @@ -7497,7 +7538,7 @@ components: properties: message: type: string - example: "Repository not registered or CI not enabled" + example: 'Repository not registered or CI not enabled' SuccessResponse_SlackWebhookArray: type: object properties: @@ -7507,7 +7548,7 @@ components: data: type: array items: - $ref: "#/components/schemas/SlackWebhookFull" + $ref: '#/components/schemas/SlackWebhookFull' SuccessResponse_SlackWebhookJSON: type: object properties: @@ -7515,7 +7556,7 @@ components: type: string example: OK data: - $ref: "#/components/schemas/SlackWebhookJSON" + $ref: '#/components/schemas/SlackWebhookJSON' CreatedResponse_SlackWebhookFull: type: object properties: @@ -7523,7 +7564,7 @@ components: type: string example: Created data: - $ref: "#/components/schemas/SlackWebhookFull" + $ref: '#/components/schemas/SlackWebhookFull' AcceptedResponse_SlackWebhookFull: type: object properties: @@ -7531,7 +7572,7 @@ components: type: string example: Accepted data: - $ref: "#/components/schemas/SlackWebhookFull" + $ref: '#/components/schemas/SlackWebhookFull' SuccessResponse_SlackMessageSent: type: object properties: @@ -7539,7 +7580,7 @@ components: type: string example: OK data: - $ref: "#/components/schemas/SlackMessageSentResult" + $ref: '#/components/schemas/SlackMessageSentResult' SuccessResponse_GitHubTokenStatus: type: object properties: @@ -7547,7 +7588,7 @@ components: type: string example: OK data: - $ref: "#/components/schemas/GitHubTokenStatus" + $ref: '#/components/schemas/GitHubTokenStatus' CreatedResponse_GitHubTokenStatus: type: object properties: @@ -7555,7 +7596,7 @@ components: type: string example: Created data: - $ref: "#/components/schemas/GitHubTokenStatus" + $ref: '#/components/schemas/GitHubTokenStatus' SuccessResponse_GitHubTokenDeleted: type: object properties: @@ -7567,7 +7608,7 @@ components: properties: message: type: string - example: "GitHub token deleted successfully" + example: 'GitHub token deleted successfully' SuccessResponse_GitHubTokenTest: type: object properties: @@ -7575,151 +7616,231 @@ components: type: string example: OK data: - $ref: "#/components/schemas/GitHubTokenTestResult" + $ref: '#/components/schemas/GitHubTokenTestResult' tags: - - name: "AI Advisor" - - name: "AI Approval Rules" - - name: "AI Approvals" - - name: "AI Apps" - - name: "AI Audit" - - name: "AI Confirmation" - - name: "AI Content" - - name: "AI Detection" - - name: "AI Trust Centre" - - name: "Agent Discovery" - - name: "Ai Trust Index" - - name: "Approval Workflows" - - name: Assessments - - name: Audit - - name: Authentication - - name: Automations - - name: "CE Marking" - - name: "Change History" - - name: Compliance - - name: "Custom Fields" - - name: Dashboard - - name: Datasets - - name: Deadlines - - name: "Demo Data" - - name: "EU AI Act" - - name: "Entity Graph" - - name: Evidence - - name: "Evidence AI" - - name: FRIA - - name: Files - - name: Frameworks - - name: "Governance OS" - - name: "ISO 27001" - - name: "ISO 42001" - - name: Incidents - - name: "Intake Forms" - - name: Integrations - - name: Internal - - name: Invitations - - name: "LLM Evals" - - name: "LLM Keys" - - name: Mail - - name: "Model Inventory" - - name: "Model Risks" - - name: "NIST AI RMF" - - name: Notes - - name: Notifications - - name: Organizations - - name: Plugins - - name: Policies - - name: "Post-Market Monitoring" - - name: "Project Risks" - - name: Projects - - name: "Quantitative Risks" - - name: Readiness - - name: Reporting - - name: "Risk Benchmarks" - - name: "Risk History" - - name: Roles - - name: "SSO Config" - - name: Search - - name: Settings - - name: "Shadow AI" - - name: "Share Links" - - name: Subscriptions - - name: "Super Admin" - - name: System - - name: Tasks - - name: Training - - name: Users - - name: "Vendor Risks" - - name: Vendors - - name: Webhooks + - + name: 'AI Advisor' + - + name: 'AI Approval Rules' + - + name: 'AI Approvals' + - + name: 'AI Apps' + - + name: 'AI Audit' + - + name: 'AI Confirmation' + - + name: 'AI Content' + - + name: 'AI Detection' + - + name: 'AI Trust Centre' + - + name: 'Agent Discovery' + - + name: 'Ai Trust Index' + - + name: 'Approval Workflows' + - + name: Assessments + - + name: Audit + - + name: Authentication + - + name: Automations + - + name: 'CE Marking' + - + name: 'Change History' + - + name: Compliance + - + name: 'Custom Fields' + - + name: Dashboard + - + name: Datasets + - + name: Deadlines + - + name: 'Demo Data' + - + name: 'EU AI Act' + - + name: 'Entity Graph' + - + name: Evidence + - + name: 'Evidence AI' + - + name: FRIA + - + name: Files + - + name: Frameworks + - + name: 'Governance OS' + - + name: 'ISO 27001' + - + name: 'ISO 42001' + - + name: Incidents + - + name: 'Intake Forms' + - + name: Integrations + - + name: Internal + - + name: Invitations + - + name: 'LLM Evals' + - + name: 'LLM Keys' + - + name: Mail + - + name: 'Model Inventory' + - + name: 'Model Risks' + - + name: 'NIST AI RMF' + - + name: Notes + - + name: Notifications + - + name: Organizations + - + name: Plugins + - + name: Policies + - + name: 'Post-Market Monitoring' + - + name: 'Project Risks' + - + name: Projects + - + name: 'Quantitative Risks' + - + name: Readiness + - + name: 'Regulations Tracker' + - + name: Reporting + - + name: 'Risk Benchmarks' + - + name: 'Risk History' + - + name: Roles + - + name: 'SSO Config' + - + name: Search + - + name: Settings + - + name: 'Shadow AI' + - + name: 'Share Links' + - + name: Subscriptions + - + name: 'Super Admin' + - + name: System + - + name: Tasks + - + name: Training + - + name: Users + - + name: 'Vendor Risks' + - + name: Vendors + - + name: Webhooks paths: /users: get: - summary: "List all users in organization" + summary: 'List all users in organization' description: "Returns all users belonging to the authenticated user's organization,\nordered by created_at DESC, id ASC. Password hashes are excluded.\n" tags: - Users security: - - bearerAuth: [] + - + bearerAuth: [] responses: - "200": - description: "Users found" + '200': + description: 'Users found' content: application/json: schema: type: object properties: - message: { type: string, example: OK } - data: { type: array, items: { $ref: "#/components/schemas/UserSafe" } } - "204": - description: "No users found (empty organization)" - "500": - description: "Internal server error" + message: {type: string, example: OK} + data: {type: array, items: {$ref: '#/components/schemas/UserSafe'}} + '204': + description: 'No users found (empty organization)' + '500': + description: 'Internal server error' operationId: getAllUsers - "/users/{id}": + '/users/{id}': get: - summary: "Get user by ID" + summary: 'Get user by ID' description: "Retrieves a single user by their numeric ID. Super-admins can access\nany user; regular users can only access users within their organization\n(or their own record).\n" tags: - Users security: - - bearerAuth: [] + - + bearerAuth: [] parameters: - - in: path + - + in: path name: id required: true schema: type: integer - description: "User ID" + description: 'User ID' responses: - "200": - description: "User found" + '200': + description: 'User found' content: application/json: schema: type: object properties: - message: { type: string, example: OK } - data: { $ref: "#/components/schemas/UserSafe" } - "403": - description: "Access denied (user belongs to different organization)" - "404": - description: "User not found" - "500": - description: "Internal server error" + message: {type: string, example: OK} + data: {$ref: '#/components/schemas/UserSafe'} + '403': + description: 'Access denied (user belongs to different organization)' + '404': + description: 'User not found' + '500': + description: 'Internal server error' operationId: getUserById patch: - summary: "Update user by ID" + summary: 'Update user by ID' description: "Updates user fields (name, surname, email, roleId, last_login).\nOnly provided fields are updated. Organization isolation enforced.\nSends Slack notification on role change. Sends email notification\nwhen role changes from Editor (3) to Admin (1).\n" tags: - Users security: - - bearerAuth: [] + - + bearerAuth: [] parameters: - - in: path + - + in: path name: id required: true schema: type: integer - description: "User ID to update" + description: 'User ID to update' requestBody: required: true content: @@ -7729,11 +7850,11 @@ paths: properties: name: type: string - description: "First name" + description: 'First name' example: Jane surname: type: string - description: "Last name" + description: 'Last name' example: Smith email: type: string @@ -7741,70 +7862,72 @@ paths: example: jane@example.com roleId: type: integer - description: "New role ID (1=Admin, 2=Reviewer, 3=Editor, 4=Auditor). Can be sent as string." + description: 'New role ID (1=Admin, 2=Reviewer, 3=Editor, 4=Auditor). Can be sent as string.' example: 1 last_login: type: string format: date-time - description: "Override last login timestamp" - description: "All fields are optional; only provided fields are updated" + description: 'Override last login timestamp' + description: 'All fields are optional; only provided fields are updated' responses: - "202": - description: "User updated" + '202': + description: 'User updated' content: application/json: schema: type: object properties: - message: { type: string, example: Accepted } - data: { $ref: "#/components/schemas/UserSafe" } - "400": - description: "Validation error" - "403": - description: "Access denied or business logic error" - "404": - description: "User not found" - "500": - description: "Internal server error" + message: {type: string, example: Accepted} + data: {$ref: '#/components/schemas/UserSafe'} + '400': + description: 'Validation error' + '403': + description: 'Access denied or business logic error' + '404': + description: 'User not found' + '500': + description: 'Internal server error' operationId: updateUserById delete: - summary: "Delete user by ID" + summary: 'Delete user by ID' description: "Deletes a user and nullifies all their foreign key references across\nprojects, vendors, risks, vendor risks, files, automations, and invitations.\nAlso removes the user from projects_members. Demo users and super-admins\ncannot be deleted.\n" tags: - Users security: - - bearerAuth: [] + - + bearerAuth: [] parameters: - - in: path + - + in: path name: id required: true schema: type: integer - description: "User ID to delete" + description: 'User ID to delete' responses: - "202": - description: "User deleted" + '202': + description: 'User deleted' content: application/json: schema: type: object properties: - message: { type: string, example: Accepted } - data: { type: boolean, description: "true if deletion succeeded" } - "403": - description: "Forbidden: demo user, super-admin, or wrong organization" + message: {type: string, example: Accepted} + data: {type: boolean, description: 'true if deletion succeeded'} + '403': + description: 'Forbidden: demo user, super-admin, or wrong organization' content: application/json: schema: - $ref: "#/components/schemas/ErrorEnvelope" - "404": - description: "User not found" - "500": - description: "Internal server error" + $ref: '#/components/schemas/ErrorEnvelope' + '404': + description: 'User not found' + '500': + description: 'Internal server error' operationId: deleteUserById /users/register: post: - summary: "Register a new user" + summary: 'Register a new user' description: "Creates a new user account. Requires a valid registration JWT (set by registerJWT middleware).\nValidates email uniqueness, password strength, and required fields.\nMarks any pending invitation as accepted after successful creation.\n" tags: - Users @@ -7824,11 +7947,11 @@ paths: properties: name: type: string - description: "User's first name" + description: 'User''s first name' example: John surname: type: string - description: "User's last name" + description: 'User''s last name' example: Doe email: type: string @@ -7837,46 +7960,46 @@ paths: password: type: string format: password - description: "Must be 8+ chars with uppercase, lowercase, and digit" + description: 'Must be 8+ chars with uppercase, lowercase, and digit' example: SecurePassword123! roleId: type: integer - description: "1=Admin, 2=Reviewer, 3=Editor, 4=Auditor" + description: '1=Admin, 2=Reviewer, 3=Editor, 4=Auditor' example: 3 organizationId: type: integer - description: "Organization to assign the user to" + description: 'Organization to assign the user to' example: 1 responses: - "201": - description: "User created successfully" + '201': + description: 'User created successfully' content: application/json: schema: type: object properties: - message: { type: string, example: Created } - data: { $ref: "#/components/schemas/UserSafe" } - "400": - description: "Validation error (missing fields, weak password, invalid email)" + message: {type: string, example: Created} + data: {$ref: '#/components/schemas/UserSafe'} + '400': + description: 'Validation error (missing fields, weak password, invalid email)' content: application/json: schema: - $ref: "#/components/schemas/ErrorEnvelope" - "403": - description: "Business logic error" - "409": - description: "User with this email already exists" + $ref: '#/components/schemas/ErrorEnvelope' + '403': + description: 'Business logic error' + '409': + description: 'User with this email already exists' content: application/json: schema: - $ref: "#/components/schemas/ErrorEnvelope" - "500": - description: "Internal server error" + $ref: '#/components/schemas/ErrorEnvelope' + '500': + description: 'Internal server error' operationId: createNewUser /users/login: post: - summary: "Authenticate user" + summary: 'Authenticate user' description: "Validates email/password credentials via bcrypt. Returns a JWT access token\nin the response body and sets a refresh token in an HTTP-only cookie.\nRate-limited to 5 requests per minute per IP.\n" tags: - Users @@ -7899,115 +8022,85 @@ paths: format: password example: SecurePassword123! responses: - "202": - description: "Authentication successful" + '202': + description: 'Authentication successful' headers: Set-Cookie: schema: type: string - description: "refresh_token=