extends: spectral:oas rules: saashub-summary-title-case: description: All operation summaries must use Title Case message: "Operation summary '{{value}}' must use Title Case" severity: warn given: "$.paths[*][*].summary" then: function: pattern functionOptions: match: "^[A-Z][a-zA-Z0-9]*(\\s[A-Z][a-zA-Z0-9]*)*$" saashub-tags-title-case: description: All tags must use Title Case message: "Tag '{{value}}' must use Title Case" severity: warn given: "$.paths[*][*].tags[*]" then: function: pattern functionOptions: match: "^[A-Z][a-zA-Z0-9]*(\\s[A-Z][a-zA-Z0-9]*)*$" saashub-api-key-required: description: API key query parameter must be present on all operations message: "All SaaSHub API operations require an api_key query parameter" severity: error given: "$.paths[*][get]" then: function: schema functionOptions: schema: type: object saashub-operation-ids-camel-case: description: Operation IDs must use camelCase message: "Operation ID '{{value}}' must use camelCase" severity: warn given: "$.paths[*][*].operationId" then: function: pattern functionOptions: match: "^[a-z][a-zA-Z0-9]*$" saashub-path-params-have-examples: description: Path parameters should include examples message: "Path parameter should include an example value" severity: warn given: "$.paths[*][*].parameters[?(@.in == 'path')]" then: field: schema.example function: truthy saashub-responses-include-json: description: Successful responses must return application/json message: "2xx responses should include application/json content" severity: warn given: "$.paths[*][*].responses[?(@property.match(/^2/))]" then: field: content function: truthy saashub-jsonapi-response-structure: description: Responses should follow JSON:API structure with data field message: "Response schema should include a 'data' property per JSON:API spec" severity: warn given: "$.components.schemas[*]" then: function: schema functionOptions: schema: type: object