Files
docs/standards/mcp/templates/app/openapi.yaml
Vishesh 'ironeagle' Bangotra 0857513fce Phase 10a: point the sample + react-openapi docs at the standards tree
- templates/app/openapi.yaml description no longer references react/vet
- react-openapi x- catalog docstring now names the standards sample as the
  reference application; refreshed the vendored react-openapi MCP module
2026-10-20 15:05:46 +05:30

1466 lines
40 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

openapi: 3.1.0
info:
title: Veterinary Clinic API
version: 0.1.0
description: |
Veterinary clinic management API — the standards reference backend pairing
with the client template and the react-openapi admin panel renderer. Every
resource is driven by OpenAPI x- extension fields; auth is bearer JWT
introspected against the auth-server.
servers:
- url: http://localhost:8020
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
x-server-url: "{AUTH_SERVER}"
x-introspect-path: "/introspect"
x-login-path: "/login"
x-register-path: "/register"
x-logout-path: "/logout"
x-me-path: "/me"
schemas:
Metadata:
type: object
x-display-format: "created:{createdOn}|updated:{updatedOn}"
properties:
createdOn:
type: string
format: date-time
updatedOn:
type: string
format: date-time
Procedure:
type: object
x-display-format: "{name} — ${cost}"
properties:
name:
type: string
x-order: 1
x-label: "Procedure Name"
description:
type: string
x-order: 2
x-label: "Description"
cost:
type: number
format: float
x-order: 3
x-label: "Cost"
notes:
$ref: '#/components/schemas/ProcedureNotes'
x-order: 4
x-label: "Notes"
ProcedureNoteBase:
type: object
properties:
summary:
type: string
x-order: 1
x-label: "Summary"
details:
type: string
x-order: 2
x-label: "Details"
ProcedureNotes:
x-display-format: "{summary}"
oneOf:
- $ref: '#/components/schemas/BasicNote'
- $ref: '#/components/schemas/HeartRateNote'
- $ref: '#/components/schemas/DentalNote'
- $ref: '#/components/schemas/VaccineNote'
- $ref: '#/components/schemas/PreOpNote'
- $ref: '#/components/schemas/SurgeryNote'
discriminator:
propertyName: noteType
mapping:
basic: BasicNote
heart_rate: HeartRateNote
dental: DentalNote
vaccine: VaccineNote
preop: PreOpNote
surgery: SurgeryNote
BasicNote:
allOf:
- $ref: '#/components/schemas/ProcedureNoteBase'
- type: object
properties:
noteType:
type: string
enum: [basic]
x-order: 0
x-label: "Type"
required: [noteType]
HeartRateNote:
allOf:
- $ref: '#/components/schemas/ProcedureNoteBase'
- type: object
properties:
noteType:
type: string
enum: [heart_rate]
x-order: 0
x-label: "Type"
bpm:
type: integer
x-order: 3
x-label: "Heart Rate (bpm)"
required: [noteType, bpm]
DentalNote:
allOf:
- $ref: '#/components/schemas/ProcedureNoteBase'
- type: object
properties:
noteType:
type: string
enum: [dental]
x-order: 0
x-label: "Type"
procedureType:
type: string
enum: [scaling, polishing]
x-order: 3
x-label: "Procedure"
teeth:
type: string
enum: [all, upper_only, lower_only]
x-order: 4
x-label: "Teeth"
required: [noteType, procedureType]
VaccineNote:
allOf:
- $ref: '#/components/schemas/ProcedureNoteBase'
- type: object
properties:
noteType:
type: string
enum: [vaccine]
x-order: 0
x-label: "Type"
medicine:
type: string
enum: [Rabies, DHPP, Tricat, Deworming]
x-order: 3
x-label: "Medicine"
leg:
type: string
enum: [front_left, front_right, hind_left, hind_right]
x-order: 4
x-label: "Injection Leg"
required: [noteType, medicine, leg]
PreOpNote:
allOf:
- $ref: '#/components/schemas/ProcedureNoteBase'
- type: object
properties:
noteType:
type: string
enum: [preop]
x-order: 0
x-label: "Type"
heartRate:
type: integer
x-order: 3
x-label: "Heart Rate (bpm)"
temperature:
type: number
format: float
x-order: 4
x-label: "Temperature (°C)"
required: [noteType, heartRate, temperature]
SurgeryNote:
allOf:
- $ref: '#/components/schemas/ProcedureNoteBase'
- type: object
properties:
noteType:
type: string
enum: [surgery]
x-order: 0
x-label: "Type"
surgeryType:
type: string
enum: [neuter, spay]
x-order: 3
x-label: "Surgery Type"
complications:
type: string
x-order: 4
x-label: "Complications"
required: [noteType, surgeryType]
Action:
type: object
x-primary-key: _received_at
x-display-format: "{action}"
x-list-columns: [action]
properties:
action:
type: string
enum: [wagging_tail, blep, stretching, showing_belly, barking, panting, purring, kneading, head_tilt, chirping, wing_flap]
x-label: "Action"
x-order: 1
x-filterable: false
required: [action]
Parent:
type: object
x-primary-key: id
x-display-format: "{name}"
x-list-columns: [name, email, phone]
properties:
id:
type: integer
readOnly: true
x-order: 0
x-hidden: { form: true, list: true }
x-label: "ID"
name:
type: string
x-order: 1
x-label: "Name"
x-description: "Parent's full name"
x-filterable: true
x-sortable: true
x-autocomplete: token
email:
type: string
format: email
x-order: 2
x-label: "Email"
x-description: "Email address"
x-filterable: true
x-autocomplete: email
phone:
type: string
x-order: 3
x-label: "Phone"
x-description: "Contact phone number"
x-filterable: true
x-autocomplete: phone
metadata:
$ref: '#/components/schemas/Metadata'
x-order: 4
x-label: "Metadata"
required: [id, name, email]
Vet:
type: object
x-primary-key: id
x-display-format: "Dr. {name}"
x-list-columns: [name, specialty, email, phone]
properties:
id:
type: integer
readOnly: true
x-order: 0
x-hidden: { form: true, list: true }
x-label: "ID"
name:
type: string
x-order: 1
x-label: "Name"
x-description: "Veterinarian's full name"
x-filterable: true
x-sortable: true
x-autocomplete: token
specialty:
type: string
x-order: 2
x-label: "Specialty"
x-description: "Area of specialization"
x-filterable: true
x-autocomplete: token
email:
type: string
format: email
x-order: 3
x-label: "Email"
x-description: "Email address"
x-filterable: true
x-autocomplete: email
phone:
type: string
x-order: 4
x-label: "Phone"
x-description: "Contact phone number"
metadata:
$ref: '#/components/schemas/Metadata'
x-order: 5
x-label: "Metadata"
required: [id, name]
Treatment:
type: object
x-primary-key: id
x-display-format: "{label}"
x-list-columns: [label, description]
properties:
id:
type: integer
readOnly: true
x-order: 0
x-hidden: { form: true, list: true }
x-label: "ID"
label:
type: string
x-order: 1
x-label: "Treatment"
x-description: "Name of the treatment"
x-filterable: true
x-sortable: true
x-autocomplete: token
description:
type: string
x-order: 2
x-label: "Description"
x-description: "Detailed description of the treatment"
x-filterable: true
x-autocomplete: text
metadata:
$ref: '#/components/schemas/Metadata'
x-order: 4
x-label: "Metadata"
required: [id, label]
Pet:
type: object
x-primary-key: id
x-display-format: "{name} – #{id}"
x-list-columns: [name, species, age, weight, birthDate, parents]
properties:
id:
type: integer
readOnly: true
x-order: 0
x-hidden: { form: true, list: true }
x-label: "ID"
name:
type: string
x-order: 1
x-label: "Pet Name"
x-description: "Name of the pet"
x-filterable: true
x-sortable: true
x-autocomplete: token
species:
type: string
enum: [dog, cat, bird]
x-order: 2
x-label: "Species"
x-description: "Type of animal"
x-filterable: true
age:
type: integer
x-order: 3
x-label: "Age"
x-description: "Age in years"
x-filterable: true
x-sortable: true
weight:
type: number
format: float
x-order: 4
x-label: "Weight"
x-description: "Weight in kilograms"
birthDate:
type: string
format: date
x-order: 5
x-label: "Date of Birth"
x-description: "Pet's birth date"
x-filterable: true
photo:
type: string
format: binary
x-ui-type: image
x-upload-url: /pets/{id}/photo
x-order: 6
x-label: "Photo"
x-description: "Upload a photo of the pet"
parents:
type: array
items:
$ref: '#/components/schemas/Parent'
x-fk:
resource: parents
x-order: 7
x-label: "Parents"
x-description: "Pet's owners"
x-filterable: true
metadata:
$ref: '#/components/schemas/Metadata'
x-order: 8
x-label: "Metadata"
required: [id, name, parents]
Appointment:
type: object
x-primary-key: id
x-display-format: "Appt #{id} – {date}"
x-list-columns: [date, pet, vet, treatment, notes]
properties:
id:
type: integer
readOnly: true
x-order: 0
x-hidden: { form: true, list: true }
x-label: "ID"
date:
type: string
format: date-time
x-order: 1
x-label: "Date & Time"
x-description: "Appointment date and time"
x-filterable: true
x-sortable: true
notes:
type: string
x-order: 2
x-label: "Notes"
x-description: "Any additional notes"
procedures:
type: array
items:
$ref: '#/components/schemas/Procedure'
x-order: 3
x-label: "Procedures"
x-description: "List of procedures performed during this appointment"
pet:
$ref: '#/components/schemas/Pet'
x-fk:
resource: pets
x-order: 4
x-label: "Pet"
x-description: "Select a pet"
x-filterable: true
vet:
$ref: '#/components/schemas/Vet'
x-fk:
resource: vets
prefetch: true
x-order: 5
x-label: "Veterinarian"
x-description: "Select a veterinarian"
x-filterable: true
treatment:
$ref: '#/components/schemas/Treatment'
x-fk:
resource: treatments
prefetch: true
x-order: 6
x-label: "Treatment"
x-description: "Select a treatment"
x-filterable: true
metadata:
$ref: '#/components/schemas/Metadata'
x-order: 7
x-label: "Metadata"
required: [id, date, pet, vet, treatment]
Job:
type: object
x-primary-key: id
x-display-format: "Job #{id} – {name}"
x-list-columns: [id, name, kind, status, retry_count, error_message]
x-hidden: false
properties:
id:
type: integer
readOnly: true
x-order: 0
x-hidden: { form: true, list: true }
x-label: "ID"
name:
type: string
x-order: 1
x-label: "Name"
x-description: "Human label for the job"
x-sortable: true
kind:
type: string
x-order: 2
x-label: "Kind"
x-description: "Dispatch key — selects the pipeline family"
x-filterable: true
x-edit-as: select
x-ui-type: enum
enum: [appointment_reminder]
status:
type: string
x-order: 3
x-label: "Status"
x-description: "Lifecycle status"
x-filterable: true
x-sortable: true
x-edit-as: select
x-ui-type: enum
enum: [pending, processing, done, failed]
payload:
type: object
additionalProperties: true
x-order: 4
x-label: "Payload"
x-description: "Job-specific input (e.g. appointment_id)"
retry_count:
type: integer
x-order: 5
x-label: "Retries"
x-description: "Failed attempts so far"
x-hidden: { form: true }
error_message:
type: string
x-order: 6
x-label: "Error"
x-description: "Last failure detail"
x-hidden: { form: true, list: true }
metadata:
$ref: '#/components/schemas/Metadata'
x-order: 7
x-label: "Metadata"
required: [id, name, kind, status]
ErrorBody:
type: object
properties:
detail:
type: string
required: [detail]
HTTPValidationError:
type: object
properties:
detail:
type: array
items:
$ref: '#/components/schemas/ValidationError'
ValidationError:
type: object
properties:
loc:
type: array
items:
type: string
msg:
type: string
type:
type: string
required: [loc, msg, type]
responses:
Unauthorized:
description: Not authenticated
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
Forbidden:
description: Insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
ValidationError:
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
InternalServerError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
paths:
/health:
get:
summary: Liveness probe (public, unauthenticated)
operationId: health
security: []
responses:
'200':
description: Service is alive
content:
application/json:
schema:
type: object
properties:
status:
type: string
service:
type: string
/parents:
get:
summary: List parents (paginated)
operationId: list_parents
parameters:
- in: query
name: limit
schema: {type: integer, default: 20}
- in: query
name: offset
schema: {type: integer, default: 0}
responses:
'200':
description: Paginated list of parents
content:
application/json:
schema:
type: object
properties:
total:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/Parent'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Create a parent
operationId: create_parent
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
responses:
'201':
description: Parent created
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/parents/{id}:
get:
operationId: get_parent
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: Single parent
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
operationId: update_parent
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
responses:
'200':
description: Parent updated
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
operationId: delete_parent
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'204':
description: Parent deleted
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/vets:
get:
summary: List vets (paginated)
operationId: list_vets
parameters:
- in: query
name: limit
schema: {type: integer, default: 20}
- in: query
name: offset
schema: {type: integer, default: 0}
responses:
'200':
description: Paginated list of vets
content:
application/json:
schema:
type: object
properties:
total:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/Vet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Create a vet
operationId: create_vet
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Vet'
responses:
'201':
description: Vet created
content:
application/json:
schema:
$ref: '#/components/schemas/Vet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/vets/{id}:
get:
operationId: get_vet
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: Single vet
content:
application/json:
schema:
$ref: '#/components/schemas/Vet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
operationId: update_vet
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Vet'
responses:
'200':
description: Vet updated
content:
application/json:
schema:
$ref: '#/components/schemas/Vet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
operationId: delete_vet
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'204':
description: Vet deleted
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/treatments:
get:
summary: List treatments (catalogue)
operationId: list_treatments
responses:
'200':
description: List of treatments
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Treatment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Add a treatment (admin only)
operationId: create_treatment
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Treatment'
responses:
'201':
description: Treatment added
content:
application/json:
schema:
$ref: '#/components/schemas/Treatment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/treatments/{id}:
get:
operationId: get_treatment
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: Single treatment
content:
application/json:
schema:
$ref: '#/components/schemas/Treatment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
operationId: update_treatment
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Treatment'
responses:
'200':
description: Treatment updated
content:
application/json:
schema:
$ref: '#/components/schemas/Treatment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
operationId: delete_treatment
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'204':
description: Treatment deleted
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/pets:
get:
summary: List pets (paginated)
operationId: list_pets
parameters:
- in: query
name: limit
schema: {type: integer, default: 20}
- in: query
name: offset
schema: {type: integer, default: 0}
responses:
'200':
description: Paginated list of pets
content:
application/json:
schema:
type: object
properties:
total:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/Pet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Create a pet
operationId: create_pet
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
responses:
'201':
description: Pet created
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/pets/{id}:
get:
operationId: get_pet
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: Single pet
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
operationId: update_pet
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
responses:
'200':
description: Pet updated
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
operationId: delete_pet
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'204':
description: Pet deleted
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Upload pet photo
operationId: upload_pet_photo
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
responses:
'200':
description: Photo uploaded
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/pets/{id}/actions:
get:
summary: Stream animal actions via SSE, scoped to a pet's species
operationId: stream_actions
x-sse: true
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: SSE stream of random animal actions (behaviors)
content:
text/event-stream:
schema:
$ref: '#/components/schemas/Action'
/appointments:
get:
summary: List appointments (paginated, filterable)
operationId: list_appointments
parameters:
- in: query
name: limit
schema: {type: integer, default: 20}
- in: query
name: offset
schema: {type: integer, default: 0}
- in: query
name: date
schema: {type: string, format: date}
- in: query
name: vet
schema: {type: integer}
- in: query
name: pet
schema: {type: integer}
responses:
'200':
description: Paginated list of appointments
content:
application/json:
schema:
type: object
properties:
total:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/Appointment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Create an appointment
operationId: create_appointment
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
responses:
'201':
description: Appointment created
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/appointments/{id}:
get:
operationId: get_appointment
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: Single appointment
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
operationId: update_appointment
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
responses:
'200':
description: Appointment updated
content:
application/json:
schema:
$ref: '#/components/schemas/Appointment'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
operationId: delete_appointment
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'204':
description: Appointment deleted
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/jobs:
get:
summary: List jobs (paginated)
operationId: list_jobs
parameters:
- in: query
name: limit
schema: {type: integer, default: 20}
- in: query
name: offset
schema: {type: integer, default: 0}
- in: query
name: status
schema: {type: string}
x-label: "Status"
x-filterable: true
responses:
'200':
description: Paginated list of jobs
content:
application/json:
schema:
type: object
properties:
total:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/Job'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
post:
summary: Create a job
operationId: create_job
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
responses:
'201':
description: Job created
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
/jobs/{id}:
get:
operationId: get_job
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'200':
description: Single job
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
operationId: update_job
parameters:
- name: id
in: path
required: true
schema: {type: integer}
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
responses:
'200':
description: Job updated
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
operationId: delete_job
parameters:
- name: id
in: path
required: true
schema: {type: integer}
responses:
'204':
description: Job deleted
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
'500':
$ref: '#/components/responses/InternalServerError'