extends: spectral:oas rules: # Authentication Rules acceldata-require-api-key-security: description: All operations must require the X-API-Key security scheme message: "Operation '{{path}}' must include apiKey security requirement" severity: error given: "$.paths[*][get,post,put,patch,delete]" then: field: security function: truthy acceldata-api-key-header-name: description: API key must use X-API-Key header name message: "Security scheme must use 'X-API-Key' as the header name" severity: error given: "$.components.securitySchemes[*][?(@.in == 'header')]" then: field: name function: pattern functionOptions: match: "^X-API-Key$" # Path Naming Rules acceldata-path-kebab-case: description: API paths must use kebab-case message: "Path '{{value}}' must use kebab-case (lowercase with hyphens)" severity: warn given: "$.paths[*]~" then: function: pattern functionOptions: match: "^(/[a-z0-9-]+({[a-zA-Z]+})?)*$" acceldata-no-trailing-slash: description: API paths must not have trailing slashes message: "Path '{{value}}' must not have a trailing slash" severity: warn given: "$.paths[*]~" then: function: pattern functionOptions: notMatch: "/$" # Response Rules acceldata-require-200-response: description: GET operations must define a 200 response message: "GET operation at '{{path}}' must define a 200 response" severity: error given: "$.paths[*].get.responses" then: field: "200" function: truthy acceldata-require-400-response: description: Operations must define a 400 error response message: "Operation at '{{path}}' must define a 400 response" severity: warn given: "$.paths[*][get,post,put,patch,delete].responses" then: field: "400" function: truthy acceldata-require-401-response: description: Operations must define a 401 unauthorized response message: "Operation at '{{path}}' must define a 401 response" severity: warn given: "$.paths[*][get,post,put,patch,delete].responses" then: field: "401" function: truthy acceldata-require-500-response: description: Operations must define a 500 server error response message: "Operation at '{{path}}' must define a 500 response" severity: warn given: "$.paths[*][get,post,put,patch,delete].responses" then: field: "500" function: truthy # Schema Rules acceldata-schema-require-description: description: All schema components must have a description message: "Schema '{{path}}' must have a description" severity: warn given: "$.components.schemas[*]" then: field: description function: truthy acceldata-schema-properties-require-description: description: Schema properties should have descriptions message: "Property at '{{path}}' should have a description" severity: info given: "$.components.schemas[*].properties[*]" then: field: description function: truthy acceldata-require-id-property: description: Resource schemas should include an id property message: "Schema '{{path}}' should include an 'id' property" severity: info given: "$.components.schemas[?(@.type == 'object' && !@.properties.total)]" then: field: properties.id function: truthy acceldata-timestamp-format: description: Timestamp fields must use date-time format message: "Timestamp property '{{path}}' must use format: date-time" severity: error given: "$.components.schemas[*].properties[?(@.description =~ /time|date|at$/i)]" then: field: format function: enumeration functionOptions: values: - date-time - date # Pagination Rules acceldata-list-schema-require-total: description: List/collection schemas must include a total count property message: "List schema '{{path}}' must include a 'total' property" severity: warn given: "$.components.schemas[?(@.title =~ /List$/)]" then: field: properties.total function: truthy acceldata-list-schema-require-page: description: List/collection schemas must include page and pageSize for pagination message: "List schema '{{path}}' must include 'page' property" severity: warn given: "$.components.schemas[?(@.title =~ /List$/)]" then: field: properties.page function: truthy # Operation Rules acceldata-operations-require-tags: description: All operations must have at least one tag message: "Operation at '{{path}}' must have at least one tag" severity: warn given: "$.paths[*][get,post,put,patch,delete]" then: field: tags function: truthy acceldata-operations-require-summary: description: All operations must have a summary message: "Operation at '{{path}}' must have a summary" severity: error given: "$.paths[*][get,post,put,patch,delete]" then: field: summary function: truthy acceldata-operations-require-operation-id: description: All operations must have an operationId message: "Operation at '{{path}}' must have an operationId" severity: error given: "$.paths[*][get,post,put,patch,delete]" then: field: operationId function: truthy acceldata-operation-id-camel-case: description: OperationIds must use camelCase message: "OperationId '{{value}}' must use camelCase" severity: warn given: "$.paths[*][get,post,put,patch,delete].operationId" then: function: pattern functionOptions: match: "^[a-z][a-zA-Z0-9]*$" # Query Parameter Rules acceldata-list-operations-support-pagination: description: List operations should support page and pageSize query parameters message: "List operation at '{{path}}' should support pagination query parameters" severity: info given: "$.paths[?(!@~.match(/\\{.*\\}/))].get.parameters[*]" then: field: name function: pattern functionOptions: match: "^(page|pageSize|limit|offset|filter|sort)$" # Content Type Rules acceldata-require-json-content-type: description: Request bodies must use application/json content type message: "Request body at '{{path}}' must use application/json" severity: error given: "$.paths[*][post,put,patch].requestBody.content" then: field: application/json function: truthy acceldata-response-require-json-content-type: description: Success responses must return application/json message: "Response at '{{path}}' must return application/json content" severity: error given: "$.paths[*][get,post,put,patch,delete].responses[200,201].content" then: field: application/json function: truthy # Info Rules acceldata-info-require-version: description: API info must include a version message: "API info must include a version" severity: error given: "$.info" then: field: version function: truthy acceldata-info-require-description: description: API info must include a description message: "API info must include a description" severity: error given: "$.info" then: field: description function: truthy # Data Quality Specific Rules acceldata-severity-values: description: Alert and rule severity must use standard values message: "Severity at '{{path}}' must be LOW, MEDIUM, HIGH, or CRITICAL" severity: warn given: "$.components.schemas[*].properties.severity" then: field: enum function: truthy acceldata-status-values: description: Alert status must use standard values message: "Status at '{{path}}' must use defined enum values" severity: warn given: "$.components.schemas[*].properties.status" then: field: enum function: truthy