Files
MobilityOps/contracts/openapi.yaml
T
NuklearRabbit c981aad2a3 docs(release): update contracts and docs for functional-completion changes
Add the new endpoints to contracts/openapi.yaml and docs/05-api-contract.md
(return-preview, the four rule-specific data-quality resolution endpoints,
search, integration status, scheduled-scan), document the role matrix and
the audit before/after exposure in docs/12-security-and-audit.md, document
each rule type's actual resolution flow in docs/07-data-quality.md
(including the deliberate evidence-fingerprint simplification and the
reopened_from/previous_decision recurrence link), document the preview/
commit relationship in docs/08-return-workflow.md, and update README.md's
scope/integration-status/quality-gate sections to match what's actually
implemented and verified now. Also drops docs/05-api-contract.md's mention
of GET /api/v1/system/status, which was never implemented.
2026-08-02 07:10:37 +02:00

347 lines
10 KiB
YAML

openapi: 3.1.0
info:
title: MobilityOps API
version: 0.1.0
description: Contract baseline for the MobilityOps proof of concept.
servers:
- url: http://localhost:8128
paths:
/health:
get:
operationId: health
responses:
'200':
description: Healthy
content:
application/json:
schema:
$ref: '#/components/schemas/Health'
/api/v1/dashboard:
get:
operationId: getDashboard
responses:
'200':
description: Persisted operational summary
content:
application/json:
schema:
$ref: '#/components/schemas/Dashboard'
/api/v1/vehicles:
get:
operationId: listVehicles
parameters:
- in: query
name: status
schema:
type: string
- in: query
name: attention_only
schema:
type: boolean
default: false
responses:
'200':
description: Vehicle list
/api/v1/vehicles/{public_ref}:
get:
operationId: getVehicle
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Vehicle detail
'404':
$ref: '#/components/responses/NotFound'
/api/v1/bookings:
get:
operationId: listBookings
responses:
'200':
description: Booking list
/api/v1/bookings/{public_ref}:
get:
operationId: getBooking
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Booking detail
/api/v1/bookings/{public_ref}/return-preview:
post:
operationId: previewVehicleReturn
description: >-
Non-mutating evaluation of what committing this return would do. Shares its
domain evaluation with the commit endpoint below so the two can never drift.
No writes, no audit event, no outbox event.
parameters:
- $ref: '#/components/parameters/PublicRef'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegisterReturnRequest'
responses:
'200':
description: Authoritative evaluation of the resulting fleet state
'409':
description: Booking is not active
/api/v1/bookings/{public_ref}/return:
post:
operationId: registerVehicleReturn
parameters:
- $ref: '#/components/parameters/PublicRef'
- in: header
name: Idempotency-Key
required: true
schema:
type: string
minLength: 8
maxLength: 128
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegisterReturnRequest'
responses:
'200':
description: Existing idempotent result replayed
'201':
description: Return registered
'409':
description: State or concurrency conflict
/api/v1/data-quality/issues:
get:
operationId: listDataQualityIssues
description: Operations Manager only.
responses:
'200':
description: Quality issues
/api/v1/data-quality/scan:
post:
operationId: runDataQualityScan
description: Manual trigger for the deterministic five-rule scan. Operations Manager only.
responses:
'200':
description: Counts of newly created issues per rule type
/api/v1/data-quality/issues/{public_ref}/merge-customers:
post:
operationId: mergeDuplicateCustomers
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Merge completed
'409':
description: Issue no longer mergeable
/api/v1/data-quality/issues/{public_ref}/provide-fields:
post:
operationId: provideMissingFields
description: >-
missing_required_field only. Resolves once nothing required remains missing;
otherwise leaves the issue open with updated evidence.
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Issue after the update (may still be open)
'409':
description: Wrong rule type or issue not open
'422':
description: Disallowed field or empty value
/api/v1/data-quality/issues/{public_ref}/resolve-odometer-regression:
post:
operationId: resolveOdometerRegression
description: >-
odometer_regression only. Either retains the canonical odometer, or corrects a
related booking's reading -- a correction below the current canonical value is
rejected, since it would not resolve the regression.
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Issue resolved
'409':
description: Wrong rule type or issue not open
'422':
description: Invalid booking reference or a correction below canonical
/api/v1/data-quality/issues/{public_ref}/resolve-overlap:
post:
operationId: resolveBookingOverlap
description: >-
booking_overlap only. Blocks one of the two overlapping bookings and
re-verifies no overlap remains before resolving.
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Issue resolved
'409':
description: Wrong rule type, issue not open, or overlap still present
'422':
description: booking_ref not one of the overlapping bookings
/api/v1/data-quality/issues/{public_ref}/apply-recommended-status:
post:
operationId: applyRecommendedVehicleStatus
description: >-
vehicle_status_conflict only. Applies the one authoritative recommendation
function's output and re-validates before resolving.
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: Applied status, reason and the resolved issue
'409':
description: Wrong rule type, issue not open, or no conflict detected
/api/v1/search:
get:
operationId: search
description: >-
Bounded typed results (vehicle, booking, data_quality_issue, section).
Data-quality and manager-only sections are filtered server-side by role.
Customers are never returned -- no customer detail route exists.
parameters:
- in: query
name: q
required: true
schema:
type: string
minLength: 1
maxLength: 100
responses:
'200':
description: Search results
/api/v1/integrations/status:
get:
operationId: getIntegrationStatus
description: >-
Truthful aggregate n8n state derived from outbox delivery counts (not just the
most recent event), plus the actual MCP Hub registration_enabled setting.
Operations Manager only.
responses:
'200':
description: n8n and MCP Hub integration status
/api/v1/integrations/n8n/scheduled-scan:
post:
operationId: n8nScheduledScan
description: >-
Triggered by the scheduled n8n quality-scan workflow. Runs the same run_scan()
the manual UI action uses; idempotent by construction.
security:
- serviceToken: []
responses:
'200':
description: Counts of newly created issues per rule type
'401':
description: Invalid service token
/api/v1/knowledge/questions:
post:
operationId: askKnowledgeQuestion
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [question]
properties:
question:
type: string
minLength: 3
maxLength: 1000
responses:
'200':
description: Grounded, insufficient or unavailable answer
content:
application/json:
schema:
$ref: '#/components/schemas/GroundedAnswer'
/api/v1/integrations/mcp/operations-summary:
get:
operationId: mcpOperationsSummary
security:
- serviceToken: []
responses:
'200':
description: Read-only operational summary
components:
securitySchemes:
serviceToken:
type: http
scheme: bearer
parameters:
PublicRef:
in: path
name: public_ref
required: true
schema:
type: string
responses:
NotFound:
description: Not found
schemas:
Health:
type: object
required: [status, service]
properties:
status:
const: ok
service:
const: mobilityops-api
Dashboard:
type: object
required: [metrics, attention_items]
properties:
metrics:
type: object
additionalProperties:
type: integer
attention_items:
type: array
items:
type: object
RegisterReturnRequest:
type: object
required: [end_odometer_km, fuel_level_percent, cleanliness_ok, damage_reported, technical_warning]
properties:
end_odometer_km:
type: integer
minimum: 0
fuel_level_percent:
type: integer
minimum: 0
maximum: 100
cleanliness_ok:
type: boolean
damage_reported:
type: boolean
technical_warning:
type: boolean
notes:
type: string
maxLength: 2000
GroundedAnswer:
type: object
required: [answer, evidence_state, sources, provider, correlation_id]
properties:
answer:
type: string
evidence_state:
enum: [grounded, insufficient, unavailable]
sources:
type: array
items:
type: object
required: [document_id, title, version, section, excerpt]
properties:
document_id: {type: string}
title: {type: string}
version: {type: string}
section: {type: string}
excerpt: {type: string}
provider:
type: string
correlation_id:
type: string