# Deliverect API Spectral Ruleset # Opinionated rules derived from the Deliverect POS, Commerce, Channel, Dispatch, # Store, Pay, CRM, Loyalty, KDS, and Gift Cards OpenAPI specifications. # Conventions observed: OpenAPI 3.1, OAuth 2.0 bearer security, camelCase parameters # and operationIds, Title Case tags, "Deliverect ..." summary prefix. extends: [] rules: # ── INFO / METADATA ─────────────────────────────────────────────── info-title-deliverect-prefix: description: API title should start with "Deliverect". severity: warn given: $.info.title then: function: pattern functionOptions: match: "^Deliverect" info-description-required: description: Info object must have a non-empty description. severity: warn given: $.info then: field: description function: truthy info-version-required: description: Info object must declare a version. severity: error given: $.info then: field: version function: truthy info-contact-required: description: A contact should be provided. severity: info given: $.info then: field: contact function: truthy # ── OPENAPI VERSION ─────────────────────────────────────────────── openapi-version-3-1: description: Specs should target OpenAPI 3.1.x. severity: warn given: $.openapi then: function: pattern functionOptions: match: "^3\\.1\\." # ── SERVERS ─────────────────────────────────────────────────────── servers-defined: description: At least one server must be defined. severity: error given: $.servers then: function: schema functionOptions: schema: type: array minItems: 1 servers-https-only: description: Server URLs must use HTTPS. severity: error given: $.servers[*].url then: function: pattern functionOptions: match: "^https://" servers-deliverect-host: description: Production/staging hosts should be on the deliverect.com domain. severity: info given: $.servers[*].url then: function: pattern functionOptions: match: "deliverect\\.com" # ── PATHS ───────────────────────────────────────────────────────── path-no-trailing-slash: description: Paths should not end with a trailing slash. severity: warn given: $.paths[*]~ then: function: pattern functionOptions: notMatch: ".+/$" path-no-double-slash: description: Paths must not contain a double slash. severity: error given: $.paths[*]~ then: function: pattern functionOptions: notMatch: "//" path-no-query-string: description: Paths must not embed a query string. severity: error given: $.paths[*]~ then: function: pattern functionOptions: notMatch: "\\?" # ── OPERATIONS ──────────────────────────────────────────────────── operation-operationid-required: description: Every operation must have an operationId. severity: error given: $.paths[*][get,post,put,patch,delete] then: field: operationId function: truthy operation-operationid-unique: description: operationId values must be unique across the document. severity: error given: $ then: function: oasOpIdUnique operation-summary-required: description: Every operation must have a summary. severity: warn given: $.paths[*][get,post,put,patch,delete] then: field: summary function: truthy operation-summary-deliverect-prefix: description: Operation summaries should start with "Deliverect". severity: warn given: $.paths[*][get,post,put,patch,delete].summary then: function: pattern functionOptions: match: "^Deliverect " operation-description-required: description: Every operation must have a description. severity: warn given: $.paths[*][get,post,put,patch,delete] then: field: description function: truthy operation-tags-required: description: Every operation must be tagged. severity: warn given: $.paths[*][get,post,put,patch,delete] then: field: tags function: truthy operation-microcks-extension: description: Operations should carry the x-microcks-operation extension for mocking. severity: info given: $.paths[*][get,post,put,patch,delete] then: field: x-microcks-operation function: truthy # ── TAGS ────────────────────────────────────────────────────────── tags-global-defined: description: A global tags array should be declared. severity: info given: $ then: field: tags function: truthy tag-title-case: description: Tag names should use Title Case. severity: warn given: $.tags[*].name then: function: pattern functionOptions: match: "^[A-Z][A-Za-z0-9]*( [A-Z][A-Za-z0-9]*)*$" tag-description: description: Global tags should have a description. severity: info given: $.tags[*] then: field: description function: truthy # ── PARAMETERS ──────────────────────────────────────────────────── parameter-description-required: description: Parameters must have a description. severity: warn given: $.paths[*][get,post,put,patch,delete].parameters[*] then: field: description function: truthy parameter-schema-required: description: Parameters must declare a schema with a type. severity: error given: $.paths[*][get,post,put,patch,delete].parameters[*].schema then: field: type function: truthy parameter-camelcase: description: Parameter names should use camelCase (Deliverect convention, e.g. channelLinkId, accountId). severity: info given: $.paths[*][get,post,put,patch,delete].parameters[?(@.in=='path' || @.in=='query')].name then: function: pattern functionOptions: match: "^[a-z][a-zA-Z0-9]*$|^_" # ── REQUEST BODIES ──────────────────────────────────────────────── request-body-json-content: description: Request bodies should offer application/json content. severity: warn given: $.paths[*][post,put,patch].requestBody.content then: field: application/json function: truthy # ── RESPONSES ───────────────────────────────────────────────────── response-success-defined: description: Operations must define at least one 2xx response. severity: warn given: $.paths[*][get,post,put,patch,delete].responses then: function: schema functionOptions: schema: type: object anyOf: - required: ['200'] - required: ['201'] - required: ['202'] - required: ['204'] response-unauthorized-defined: description: Operations should document a 401 response (OAuth tokens can be rejected). severity: info given: $.paths[*][get,post,put,patch,delete].responses then: field: '401' function: truthy response-description-required: description: Every response must have a description. severity: warn given: $.paths[*][get,post,put,patch,delete].responses[*] then: field: description function: truthy # ── SECURITY ────────────────────────────────────────────────────── security-global-defined: description: A global security requirement should be declared (OAuth 2.0). severity: warn given: $ then: field: security function: truthy security-oauth2-scheme: description: An OAuth 2.0 security scheme should be defined in components. severity: warn given: $.components.securitySchemes then: field: oauth2 function: truthy # ── HTTP METHOD CONVENTIONS ─────────────────────────────────────── get-no-request-body: description: GET operations must not declare a request body. severity: error given: $.paths[*].get then: field: requestBody function: falsy # ── GENERAL QUALITY ─────────────────────────────────────────────── schema-property-examples: description: Encourage examples on schema properties for richer mocks. severity: info given: $.paths[*][get,post,put,patch,delete].responses[*].content.application/json.schema.properties[*] then: field: example function: truthy