extends: spectral:oas rules: # Xweather API follows a consistent pattern of location-based paths and # client_id/client_secret query parameter authentication xweather-operation-has-summary: description: All Xweather API operations must have a summary. message: Operation must have a summary. severity: error given: $.paths[*][get,post,put,delete,patch] then: field: summary function: truthy xweather-operation-has-tags: description: All Xweather API operations must be tagged. message: Operation must include at least one tag. severity: warn given: $.paths[*][get,post,put,delete,patch] then: field: tags function: truthy xweather-operation-has-operation-id: description: All operations must have an operationId. message: Operation must have an operationId. severity: error given: $.paths[*][get,post,put,delete,patch] then: field: operationId function: truthy xweather-operation-has-description: description: All Xweather operations must include a description explaining the data returned. message: Operation must have a description. severity: warn given: $.paths[*][get,post,put,delete,patch] then: field: description function: truthy xweather-response-200-present: description: All GET operations must define a 200 success response. message: GET operations must have a 200 response defined. severity: error given: $.paths[*].get then: field: responses.200 function: truthy xweather-path-uses-kebab-case: description: All path segments must use kebab-case. message: Path segments must use kebab-case (lowercase with hyphens, no underscores or camelCase). severity: warn given: $.paths then: field: "@key" function: pattern functionOptions: match: "^(/[a-z0-9{}-]+)+$" xweather-operation-id-camel-case: description: operationId values should use camelCase. message: operationId must use camelCase. severity: warn given: $.paths[*][get,post,put,delete,patch].operationId then: function: pattern functionOptions: match: "^[a-z][a-zA-Z0-9]*$" xweather-tags-title-case: description: Tags must use Title Case. message: Tag names must use Title Case (e.g., "Air Quality" not "air quality"). severity: warn given: $.tags[*].name then: function: pattern functionOptions: match: "^[A-Z][a-zA-Z0-9 ]*$" xweather-info-has-contact: description: API info must include contact information. message: info.contact must be defined. severity: warn given: $.info then: field: contact function: truthy xweather-schemas-have-descriptions: description: All schema properties should have descriptions. message: Schema properties should include a description. severity: hint given: $.components.schemas[*].properties[*] then: field: description function: truthy xweather-success-response-has-content: description: Success responses must define content. message: 200/201 responses must include a content definition. severity: error given: $.paths[*][*].responses[200,201] then: field: content function: truthy