claude generated openapi spec

quotesdb
Elijah Voigt 3 months ago
parent 1c90c0fac1
commit 75876988e0

@ -53,6 +53,12 @@
# NBD task management # NBD task management
nbd.packages.${system}.nbd nbd.packages.${system}.nbd
# MCP servers
pkgs.nodejs
# OpenAPI Linter
pkgs.redocly
]; ];
shellHook = '' shellHook = ''

@ -0,0 +1,393 @@
openapi: "3.1.0"
info:
title: QuotesDB API
description: A simple quotes database with passphrase-based quote ownership.
version: "0.1.0"
license:
name: MIT OR Apache-2.0
servers:
- url: http://localhost:8787
description: Local development
- url: https://api.quotesdb.example.com
description: Production (Cloudflare Workers)
# ---------------------------------------------------------------------------
# Security
# ---------------------------------------------------------------------------
# Auth is per-quote: each quote has a 4-word passphrase (auth_code) that was
# returned at creation time. Callers supply it via the X-Auth-Code header for
# mutating operations (POST /:id, DELETE /:id).
components:
securitySchemes:
AuthCode:
type: apiKey
in: header
name: X-Auth-Code
description: >
4-word passphrase returned when the quote was created
(e.g. ocean-table-purple-storm). Required for update and delete.
# -------------------------------------------------------------------------
# Schemas
# -------------------------------------------------------------------------
schemas:
# Returned for all GET responses — auth_code intentionally omitted.
Quote:
type: object
required:
- id
- text
- author
- tags
- created_at
- updated_at
properties:
id:
type: string
description: NanoID (~21 characters).
example: "V1StGXR8_Z5jdHi6B-myT"
text:
type: string
description: The quote text.
example: "The only way to do great work is to love what you do."
author:
type: string
description: The person attributed with the quote.
example: "Steve Jobs"
source:
type: ["string", "null"]
description: Optional source (book, speech, etc.).
example: "Stanford Commencement Address, 2005"
date:
type: ["string", "null"]
format: date
description: Optional ISO 8601 date (YYYY-MM-DD) associated with the quote.
example: "2005-06-12"
tags:
type: array
items:
type: string
description: Zero or more tags attached to the quote.
example: ["work", "inspiration"]
created_at:
type: string
format: date-time
description: When the quote was first stored (UTC).
updated_at:
type: string
format: date-time
description: When the quote was last modified (UTC).
# Returned only from the create (PUT) endpoint — includes auth_code.
QuoteCreated:
allOf:
- $ref: "#/components/schemas/Quote"
- type: object
required:
- auth_code
properties:
auth_code:
type: string
description: >
4-word passphrase that authorises future edits and deletes.
Store this — it cannot be recovered later.
example: "ocean-table-purple-storm"
# Request body for PUT /api/quotes (create).
QuoteCreateRequest:
type: object
required:
- text
- author
properties:
text:
type: string
description: The quote text.
author:
type: string
description: The person attributed with the quote.
source:
type: string
description: Optional source (book, speech, etc.).
date:
type: string
format: date
description: Optional ISO 8601 date (YYYY-MM-DD).
tags:
type: array
items:
type: string
description: Zero or more tags.
default: []
auth_code:
type: string
description: >
Optional custom auth code. If omitted, a 4-word passphrase is
auto-generated by the server and returned in the response.
# Request body for POST /api/quotes/:id (update — all fields optional).
QuoteUpdateRequest:
type: object
properties:
text:
type: string
description: Replacement quote text.
author:
type: string
description: Replacement author name.
source:
type: ["string", "null"]
description: Replacement source. Pass null to clear.
date:
type: ["string", "null"]
format: date
description: Replacement date. Pass null to clear.
tags:
type: array
items:
type: string
description: Replacement tag list. Replaces all existing tags.
# Paginated list of quotes.
QuoteList:
type: object
required:
- quotes
- page
- total_pages
- total_count
properties:
quotes:
type: array
items:
$ref: "#/components/schemas/Quote"
page:
type: integer
minimum: 1
description: Current page number.
total_pages:
type: integer
description: Total number of pages given the current filters.
total_count:
type: integer
description: Total number of quotes matching the current filters.
# Standard error envelope used by all error responses.
Error:
type: object
required:
- error
properties:
error:
type: string
description: Human-readable error message.
example: "quote not found"
# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------
# IMPORTANT — router registration order for the Rust implementation:
# GET /api/quotes/random must be registered BEFORE GET /api/quotes/{id}
# to prevent "random" being matched as an id parameter.
paths:
/api/:
get:
operationId: getOpenApiSpec
summary: OpenAPI specification
description: Returns this OpenAPI specification as JSON.
tags: [meta]
responses:
"200":
description: The OpenAPI spec in JSON format.
content:
application/json:
schema:
type: object
description: Raw OpenAPI 3.1 document.
/api/quotes:
get:
operationId: listQuotes
summary: List quotes
description: Returns a paginated list of quotes, optionally filtered by author or tag.
tags: [quotes]
parameters:
- name: page
in: query
description: Page number (1-based).
required: false
schema:
type: integer
minimum: 1
default: 1
- name: author
in: query
description: Filter by exact author name (case-insensitive).
required: false
schema:
type: string
- name: tag
in: query
description: Filter to quotes that have this tag.
required: false
schema:
type: string
responses:
"200":
description: Paginated list of quotes.
content:
application/json:
schema:
$ref: "#/components/schemas/QuoteList"
put:
operationId: createQuote
summary: Create a quote
description: >
Creates a new quote. If auth_code is omitted from the request body,
the server auto-generates a 4-word passphrase and returns it in the
response. Store the auth_code — it cannot be recovered later.
tags: [quotes]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/QuoteCreateRequest"
responses:
"201":
description: Quote created successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/QuoteCreated"
"422":
description: Validation error (e.g. missing required fields).
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
# NOTE: registered before /api/quotes/{id} in the Rust router.
/api/quotes/random:
get:
operationId: getRandomQuote
summary: Random quote
description: Returns a single randomly selected quote.
tags: [quotes]
responses:
"200":
description: A random quote.
content:
application/json:
schema:
$ref: "#/components/schemas/Quote"
"404":
description: No quotes exist in the database.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/api/quotes/{id}:
parameters:
- name: id
in: path
required: true
description: NanoID of the quote (~21 characters).
schema:
type: string
example: "V1StGXR8_Z5jdHi6B-myT"
get:
operationId: getQuote
summary: Get a quote by ID
description: Returns a single quote identified by its NanoID.
tags: [quotes]
responses:
"200":
description: The requested quote.
content:
application/json:
schema:
$ref: "#/components/schemas/Quote"
"404":
description: Quote not found.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
operationId: updateQuote
summary: Update a quote
description: >
Partially updates an existing quote. Only the fields included in the
request body are modified. Requires the quote's auth_code via the
X-Auth-Code header.
tags: [quotes]
security:
- AuthCode: []
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/QuoteUpdateRequest"
responses:
"200":
description: The updated quote.
content:
application/json:
schema:
$ref: "#/components/schemas/Quote"
"403":
description: Auth code missing or incorrect.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"404":
description: Quote not found.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
delete:
operationId: deleteQuote
summary: Delete a quote
description: >
Permanently deletes a quote. Requires the quote's auth_code via the
X-Auth-Code header.
tags: [quotes]
security:
- AuthCode: []
responses:
"204":
description: Quote deleted successfully. No response body.
"403":
description: Auth code missing or incorrect.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"404":
description: Quote not found.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
# ---------------------------------------------------------------------------
# Tags (for grouping in generated docs)
# ---------------------------------------------------------------------------
tags:
- name: meta
description: API metadata endpoints.
- name: quotes
description: CRUD operations on quotes.
Loading…
Cancel
Save