Veli · API Governance Rules

Veli API Rules

Spectral linting rules defining API design standards and conventions for Veli.

36 Rules error 13 warn 22 info 1
View Rules File View on GitHub

Rule Categories

no query schema servers veli

Rules

error
veli-info-title-exists
API must have an info.title
$.info
warn
veli-info-description-exists
API must have an info.description
$.info
error
veli-info-version-exists
API must have an info.version
$.info
error
veli-openapi-version-3
API must use OpenAPI 3.x
$
warn
veli-servers-exist
API must define at least one server
$
warn
veli-server-url-https
Server URL should use HTTPS
$.servers[*]
error
veli-paths-exist
API must define at least one path
$
warn
veli-path-lowercase
Path segments should use lowercase and hyphens
$.paths[*]~
error
veli-operation-summary-exists
Every operation must have a summary
$.paths[*][get,post,put,patch,delete]
warn
veli-operation-description-exists
Every operation should have a description
$.paths[*][get,post,put,patch,delete]
error
veli-operation-id-exists
Every operation must have an operationId
$.paths[*][get,post,put,patch,delete]
warn
veli-operation-id-camel-case
operationId should be camelCase
$.paths[*][get,post,put,patch,delete].operationId
warn
veli-operation-tags-exist
Every operation should have at least one tag
$.paths[*][get,post,put,patch,delete]
warn
veli-tags-defined
All tags used in operations should be defined at root level
$
warn
veli-parameter-description-exists
All parameters should have a description
$.paths[*][get,post,put,patch,delete].parameters[*]
error
veli-parameter-schema-exists
All parameters must have a schema
$.paths[*][get,post,put,patch,delete].parameters[*]
warn
veli-request-body-description
Request bodies should have a description
$.paths[*][post,put,patch].requestBody
error
veli-request-body-content
Request bodies must define content
$.paths[*][post,put,patch].requestBody
error
veli-responses-exist
Every operation must define responses
$.paths[*][get,post,put,patch,delete]
error
veli-response-success-exists
Every operation must have a 2xx success response
$.paths[*][get,post,put,patch,delete].responses
error
veli-response-description-exists
All responses must have a description
$.paths[*][get,post,put,patch,delete].responses[*]
warn
veli-schema-description-exists
All named schemas should have a description
$.components.schemas[*]
warn
veli-schema-properties-described
Schema properties should have descriptions
$.components.schemas[*].properties[*]
warn
veli-security-defined
API should define security schemes
$.components
warn
veli-security-applied
API should apply security at the root level or per operation
$
error
veli-bearer-auth-scheme
Bearer auth should use http type with bearer scheme
$.components.securitySchemes[?(@.type=='http')]
warn
veli-portfolio-response-schema
Portfolio endpoints should return schema-referenced responses
$.paths['/portfolios'][get,post].responses[200,201].content['application/json'].schema
warn
veli-strategy-id-parameter
Strategy path parameters should be named strategyId
$.paths['/strategies/{strategyId}'][*].parameters[?(@.in=='path')]
warn
veli-portfolio-id-parameter
Portfolio path parameters should be named portfolioId
$.paths['/portfolios/{portfolioId}'][*].parameters[?(@.in=='path')]
error
veli-no-empty-paths
Paths object should not be empty
$.paths
warn
veli-components-schemas-exist
API should define reusable schemas in components
$.components
warn
servers-expected-domain
Server URLs should be on the veli.io domain.
$.servers[*].url
warn
query-params-casing
Query parameters should be snake_case (the dominant convention in this API).
$.paths[*][get,post,put,patch,delete].parameters[?(@.in=='query')]
warn
schema-names-casing
Component schema names should be PascalCase (the dominant convention in this API).
$.components.schemas
info
schema-properties-casing
Schema properties should be camelCase (the dominant convention in this API).
$.components.schemas[*].properties
warn
no-empty-descriptions
Descriptions must not be empty strings.
$..description

Spectral Ruleset

Raw ↑
# veli — Spectral ruleset (strengthened)
# Plain Spectral. Existing hand-authored rules preserved; measured rules added
# from this provider's own OpenAPI conventions by strengthen_ruleset.py,
# then self-validated against the spec.
#
# Provenance:
#   - servers-https-only: 100% of servers already https (error)
#   - servers-expected-domain: 1/1 servers on veli.io
#   - path-params-casing: camel @ 100% (n=6)
#   - query-params-casing: snake @ 78% (n=9)
#   - operationid-casing: camel @ 100% (n=9)
#   - schema-names-casing: pascal @ 100% (n=12)
#   - schema-properties-casing: camel @ 52% (n=54)
#   - security: global (root) — NOT emitting operation-security-required
#   - pagination params observed: ['limit', 'offset']
#   - merge: kept 31 existing, added 5 measured, upgraded 0
#   - added: servers-expected-domain, query-params-casing, schema-names-casing, schema-properties-casing, no-empty-descriptions
extends:
  - spectral:oas
rules:
  veli-info-title-exists:
    description: API must have an info.title
    severity: error
    given: $.info
    then:
      field: title
      function: truthy
  veli-info-description-exists:
    description: API must have an info.description
    severity: warn
    given: $.info
    then:
      field: description
      function: truthy
  veli-info-version-exists:
    description: API must have an info.version
    severity: error
    given: $.info
    then:
      field: version
      function: truthy
  veli-openapi-version-3:
    description: API must use OpenAPI 3.x
    severity: error
    given: $
    then:
      field: openapi
      function: pattern
      functionOptions:
        match: ^3\.
  veli-servers-exist:
    description: API must define at least one server
    severity: warn
    given: $
    then:
      field: servers
      function: truthy
  veli-server-url-https:
    description: Server URL should use HTTPS
    severity: warn
    given: $.servers[*]
    then:
      field: url
      function: pattern
      functionOptions:
        match: ^https://
  veli-paths-exist:
    description: API must define at least one path
    severity: error
    given: $
    then:
      field: paths
      function: truthy
  veli-path-lowercase:
    description: Path segments should use lowercase and hyphens
    severity: warn
    given: $.paths[*]~
    then:
      function: pattern
      functionOptions:
        match: ^/[a-z0-9/{}_-]*$
  veli-operation-summary-exists:
    description: Every operation must have a summary
    severity: error
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: summary
      function: truthy
  veli-operation-description-exists:
    description: Every operation should have a description
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: description
      function: truthy
  veli-operation-id-exists:
    description: Every operation must have an operationId
    severity: error
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: operationId
      function: truthy
  veli-operation-id-camel-case:
    description: operationId should be camelCase
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].operationId
    then:
      function: pattern
      functionOptions:
        match: ^[a-z][a-zA-Z0-9]*$
  veli-operation-tags-exist:
    description: Every operation should have at least one tag
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: tags
      function: truthy
  veli-tags-defined:
    description: All tags used in operations should be defined at root level
    severity: warn
    given: $
    then:
      field: tags
      function: truthy
  veli-parameter-description-exists:
    description: All parameters should have a description
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].parameters[*]
    then:
      field: description
      function: truthy
  veli-parameter-schema-exists:
    description: All parameters must have a schema
    severity: error
    given: $.paths[*][get,post,put,patch,delete].parameters[*]
    then:
      field: schema
      function: truthy
  veli-request-body-description:
    description: Request bodies should have a description
    severity: warn
    given: $.paths[*][post,put,patch].requestBody
    then:
      field: description
      function: truthy
  veli-request-body-content:
    description: Request bodies must define content
    severity: error
    given: $.paths[*][post,put,patch].requestBody
    then:
      field: content
      function: truthy
  veli-responses-exist:
    description: Every operation must define responses
    severity: error
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: responses
      function: truthy
  veli-response-success-exists:
    description: Every operation must have a 2xx success response
    severity: error
    given: $.paths[*][get,post,put,patch,delete].responses
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          anyOf:
          - required:
            - '200'
          - required:
            - '201'
          - required:
            - '204'
  veli-response-description-exists:
    description: All responses must have a description
    severity: error
    given: $.paths[*][get,post,put,patch,delete].responses[*]
    then:
      field: description
      function: truthy
  veli-schema-description-exists:
    description: All named schemas should have a description
    severity: warn
    given: $.components.schemas[*]
    then:
      field: description
      function: truthy
  veli-schema-properties-described:
    description: Schema properties should have descriptions
    severity: warn
    given: $.components.schemas[*].properties[*]
    then:
      field: description
      function: truthy
  veli-security-defined:
    description: API should define security schemes
    severity: warn
    given: $.components
    then:
      field: securitySchemes
      function: truthy
  veli-security-applied:
    description: API should apply security at the root level or per operation
    severity: warn
    given: $
    then:
      field: security
      function: truthy
  veli-bearer-auth-scheme:
    description: Bearer auth should use http type with bearer scheme
    severity: error
    given: $.components.securitySchemes[?(@.type=='http')]
    then:
      field: scheme
      function: pattern
      functionOptions:
        match: ^bearer$
  veli-portfolio-response-schema:
    description: Portfolio endpoints should return schema-referenced responses
    severity: warn
    given: $.paths['/portfolios'][get,post].responses[200,201].content['application/json'].schema
    then:
      function: truthy
  veli-strategy-id-parameter:
    description: Strategy path parameters should be named strategyId
    severity: warn
    given: $.paths['/strategies/{strategyId}'][*].parameters[?(@.in=='path')]
    then:
      field: name
      function: pattern
      functionOptions:
        match: ^strategyId$
  veli-portfolio-id-parameter:
    description: Portfolio path parameters should be named portfolioId
    severity: warn
    given: $.paths['/portfolios/{portfolioId}'][*].parameters[?(@.in=='path')]
    then:
      field: name
      function: pattern
      functionOptions:
        match: ^portfolioId$
  veli-no-empty-paths:
    description: Paths object should not be empty
    severity: error
    given: $.paths
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          minProperties: 1
  veli-components-schemas-exist:
    description: API should define reusable schemas in components
    severity: warn
    given: $.components
    then:
      field: schemas
      function: truthy
  servers-expected-domain:
    description: Server URLs should be on the veli.io domain.
    severity: warn
    given: $.servers[*].url
    then:
      function: pattern
      functionOptions:
        match: veli\.io
  query-params-casing:
    description: Query parameters should be snake_case (the dominant convention in this API).
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].parameters[?(@.in=='query')]
    then:
      field: name
      function: casing
      functionOptions:
        type: snake
  schema-names-casing:
    description: Component schema names should be PascalCase (the dominant convention in this API).
    severity: warn
    given: $.components.schemas
    then:
      field: '@key'
      function: casing
      functionOptions:
        type: pascal
  schema-properties-casing:
    description: Schema properties should be camelCase (the dominant convention in this API).
    severity: info
    given: $.components.schemas[*].properties
    then:
      field: '@key'
      function: pattern
      functionOptions:
        match: ^[a-z][A-Za-z0-9]*$
  no-empty-descriptions:
    description: Descriptions must not be empty strings.
    severity: warn
    given: $..description
    then:
      function: truthy