extends: - spectral:oas formats: - oas3_1 rules: # Title Case operation summaries with Kushki prefix kushki-summary-title-case-with-prefix: description: Operation summaries must use Title Case and start with "Kushki". message: '{{property}} summary should start with "Kushki" and use Title Case (e.g. "Kushki Create Card Charge").' severity: error given: $.paths[*][*].summary then: function: pattern functionOptions: match: '^Kushki(\s+[A-Z0-9][a-zA-Z0-9]*(\s+(With|And|Or|To|For|By|Of|In|On|A|An|The))*)+(\s+[A-Z0-9][a-zA-Z0-9]*)*$' # Description present kushki-operation-description: description: Every operation must have a description. severity: warn given: $.paths[*][get,post,put,patch,delete] then: field: description function: truthy # operationId camelCase kushki-operation-id-camel-case: description: operationId must be camelCase. severity: error given: $.paths[*][*].operationId then: function: pattern functionOptions: match: '^[a-z][a-zA-Z0-9]+$' # Servers must include production + UAT kushki-servers-defined: description: Each OpenAPI document must declare at least one server. severity: error given: $.servers then: function: schema functionOptions: schema: type: array minItems: 1 # Server hosts must be Kushki kushki-server-host-allowed: description: Servers must point at *.kushkipagos.com. severity: error given: $.servers[*].url then: function: pattern functionOptions: match: '^https://api(-uat|-stg)?\.kushkipagos\.com($|/)' # Auth via Public-Merchant-Id or Private-Merchant-Id only kushki-security-scheme-merchant-id: description: SecuritySchemes must use the Public-Merchant-Id or Private-Merchant-Id apiKey header. severity: error given: $.components.securitySchemes[*] then: function: schema functionOptions: schema: type: object required: [type, in, name] properties: type: const: apiKey in: const: header name: enum: - Public-Merchant-Id - Private-Merchant-Id # Money objects must always carry currency kushki-amount-requires-currency: description: Amount/money schemas must require currency. severity: warn given: $.components.schemas[?(@.properties && @.properties.currency)] then: field: required function: schema functionOptions: schema: type: array contains: const: currency # Currency must be one of the LatAm currencies Kushki supports kushki-currency-enum: description: Currency enums must match the LatAm currencies Kushki supports. severity: warn given: $..properties.currency.enum then: function: schema functionOptions: schema: type: array items: enum: [USD, COP, PEN, CLP, MXN, BRL] # Card collection paths must live under /card/v1 kushki-card-path-prefix: description: Card operations must be exposed under /card/v1. severity: warn given: $.paths then: function: pattern functionOptions: match: '^(/card/v1|/cash/v1|/transfer/v1|/payouts/transfer/v1|/subscriptions/v1|/cardpresent/v1|/merchant/v1|/v1/charges)'