openapi

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package openapi builds the committed OpenAPI 3.1 / JSON-Schema artifacts from the Go schema source. This schema module is the source of truth; the village vendors + serves + enforces these specs (GH #53). Every spec is generated by a Build*Spec function and emitted (byte-for-byte) to generated/ at the module root by GenerateSpecArtifacts; the codegen-freshness test (cmd/schema-gen) diffs the committed copies against a fresh regen and fails on any drift.

Versioning policy (doc-surface semver)

Each spec carries its OWN info.version, which is an INDEPENDENT doc-surface semantic version describing that spec's API SURFACE — not a shared release number across specs:

  • Additive change (new route, new schema/component, new enum value) ⇒ MINOR bump.
  • Breaking change (removed/renamed route or field, changed type, tightened constraint) ⇒ MAJOR bump.

Example: adding the /api/v1/pull surface to the village-api spec was purely additive, so VillageAPIVersion went 0.1.0 → 0.2.0 (minor).

This doc-surface semver is a SEPARATE axis from the runtime WIRE-CONTRACT versions. The push/pull content contracts are negotiated at runtime via the [Min, Current] windows in internal/defaults/schema.go (PushContractVersion / PullContractVersion) over GET /api/v1/schema/version. Those windows govern whether a given CLI may talk to a given village; the spec's info.version only documents the HTTP surface. The two move independently — EXCEPT that an envelope-SHAPE change (a breaking change to the publish/pull wire envelope) is simultaneously a contract-version bump (it shifts the negotiated window) AND a spec major bump (the documented surface changed). A spec-only additive bump does NOT touch the contract windows, and a window slide that does not alter the HTTP surface does NOT bump the spec.

Single source per spec

Each spec's version is written in EXACTLY ONE place — the const block in artifacts.go (VillageAPIVersion, PeasantLocalAPIVersion, TypesVersion). That const feeds, by derivation and never by retyping:

  • info.version, via WithVersion(<Const>) in each Build*Spec function;
  • the versioned artifact filename (e.g. "village-api-0.2.0.json"), in GenerateSpecArtifacts;
  • the human-readable doc labels ("Village API v0.2.0") in cmd/schema-gen;
  • the freshness test's artifact-key assertions.

To cut a new spec version, edit ONLY the relevant const and run `go run ./cmd/schema-gen` (NOT `go generate ./...`, which no-ops on this nested module). Filenames are versioned; there is no unversioned "latest" alias.

Publish-body enforcement schema (derived, not separately reflected)

The village ENFORCES incoming publish bodies (422 on schema violation) against a standalone PublishRequest JSON Schema it vendors as backend/internal/handler/openapispec/publish-request.schema.json. That schema is produced by BuildPublishRequestSchema, which extracts the operation-specific publish body component — with its full transitive $ref closure, bundled into "$defs" — out of the village-api spec itself (JSON Schema 2020-12, the dialect the village's santhosh-tekuri validator supports). Deriving the enforced schema FROM the documented spec (rather than a separate reflector) means the two can never drift. Its filename and "$id" are versioned by VillageAPIVersion, the spec it is extracted from.

This REPLACED the retired legacy builders BuildJSONSchema + BuildOpenAPISpec (which emitted the push-contract-keyed "openapi-<v>.{json,yaml}" artifacts). The retirement is pinned by an enforcement-PARITY gate (publish_schema_parity_test.go): a frozen copy of the old BuildJSONSchema output (testdata/legacy-publish-request.schema.json) and the new extracted schema must return IDENTICAL accept/reject verdicts across a corpus of valid + malformed bodies. See GH #53.

Index

Constants

View Source
const (
	// VillageAPIVersion is the info.version of the Village API spec.
	VillageAPIVersion = schema.VillageAPIVersion
	// PeasantLocalAPIVersion is the info.version of the local dashboard API spec.
	PeasantLocalAPIVersion = schema.PeasantLocalAPIVersion
	// TypesVersion is the info.version of the types spec.
	TypesVersion = schema.TypesVersion
)

Versioned-spec info.version values are re-exported from the root schema package (the single source of truth — see versions.go there). The spec builders in this package reference them unqualified, and the root accessor schema.VillageAPISpecJSON() keys its embedded-bytes lookup off the same constants, so a version bump stays a one-line edit at the root and flows here automatically. They are kept exported here for backward compatibility with existing openapi.* call sites.

Variables

This section is empty.

Functions

func AddPeasantLocalExamples

func AddPeasantLocalExamples(spec *openapi31.Spec)

AddPeasantLocalExamples injects operation-level response examples into the local dashboard API spec.

func AddVillageExamples

func AddVillageExamples(spec *openapi31.Spec)

AddVillageExamples injects operation-level examples into the village API spec. Covers POST /api/v1/transcripts/publish request body and 200 response.

func BuildAnnotationPushRequestSchema

func BuildAnnotationPushRequestSchema(version string) ([]byte, error)

BuildAnnotationPushRequestSchema extracts the operation-compatible AnnotationPushRequest component into a standalone JSON Schema 2020-12 document. schema.ValidateAnnotationPushRequest compiles these exact generated bytes before applying the typed relational validation that JSON Schema cannot express, so a Village handler can enforce the documented and canonical request contract without recreating either rule set.

func BuildPeasantLocalAPISpec

func BuildPeasantLocalAPISpec() (*openapi31.Spec, error)

BuildPeasantLocalAPISpec builds an OpenAPI 3.1 specification for the local web dashboard API v1.0. It includes REST routes (/health, /sessions, /config/mock, /shutdown) and WebSocket channel message schemas (DashboardPayload, SessionsPayload, SessionDetailPayload, TrendsPayload, QualityPayload) as JSON Schema components.

func BuildPublishRequestSchema

func BuildPublishRequestSchema(version string) ([]byte, error)

BuildPublishRequestSchema EXTRACTS the PublishRequest component — with all of its transitive $ref dependencies, bundled and self-contained — out of the village-api OpenAPI 3.1 spec into a standalone JSON Schema 2020-12 document.

This is the SINGLE SOURCE OF TRUTH for the village's publish-body enforcement: the village vendors the bytes returned here as backend/internal/handler/openapispec/publish-request.schema.json and compiles them with santhosh-tekuri/jsonschema to reject malformed publish bodies (422). Deriving it from the village-api spec (rather than a separate reflector) means the documented HTTP surface and the enforced wire schema can never drift — they come from one Build*Spec function (GH #53: peasant is the source of truth, the village vendors + enforces).

The returned document:

  • sets "$schema" to the JSON Schema 2020-12 dialect (pinned explicitly so the village validator selects the right draft);
  • sets "$id" to urn:peasant:publish-request:<VillageAPIVersion> (derived from the single-source version const, never retyped);
  • hoists OpenapiAuthoritativeTranscriptPublishRequest's own keywords to the root;
  • bundles every transitively-referenced component under "$defs", with all "#/components/schemas/X" $refs rewritten to "#/$defs/X".

version is the doc-surface version stamped into "$id" (callers pass VillageAPIVersion).

func BuildTypesSpec

func BuildTypesSpec() (*openapi31.Spec, error)

BuildTypesSpec builds the comprehensive OpenAPI 3.1 type catalog. It has no paths: the named components are the canonical cross-language contract.

func BuildVillageAPISpec

func BuildVillageAPISpec() (*openapi31.Spec, error)

BuildVillageAPISpec builds the current OpenAPI 3.1 specification for the Village API. It describes transcript publishing, CLI authentication, annotation registry and manifest synchronization, schema negotiation, and group-scoped transcript discovery and pull operations.

Types

type AuthoritativeTranscriptPublishRequest

type AuthoritativeTranscriptPublishRequest schema.AuthoritativePublishRequest

AuthoritativeTranscriptPublishRequest is the Village 0.11 publish operation's HTTP body. Its distinct operation-only identity lets the successor OpenAPI contract be stricter than legacy shared metadata schemas.

type SpecArtifacts

type SpecArtifacts map[string][]byte

SpecArtifacts is the set of generated OpenAPI spec files, keyed by filename (e.g. "village-api-0.2.0.json"), each mapping to the exact bytes written to generated/ at the module root. It is the single source of truth for what the generator emits, shared by cmd/schema-gen (which writes them) and the codegen-freshness test (which diffs them against the committed copies). It does NOT include the HTML docs/CLI reference — those are non-contract artifacts.

func GenerateSpecArtifacts

func GenerateSpecArtifacts() (SpecArtifacts, error)

GenerateSpecArtifacts builds every committed OpenAPI JSON/YAML spec from the Go schema source and returns them as filename->bytes. The marshaling here MUST match cmd/schema-gen exactly (both call this function), so a clean tree regenerates byte-for-byte and the freshness test only fails on real drift.

type TranscriptPublishRequest

type TranscriptPublishRequest = AuthoritativeTranscriptPublishRequest

TranscriptPublishRequest retains the previous operation-wrapper name while Go consumers migrate to AuthoritativeTranscriptPublishRequest. Deprecated: use AuthoritativeTranscriptPublishRequest. See schema issue #55.

type TranscriptUpdateErrorResponse

type TranscriptUpdateErrorResponse struct {
	// Error is the human-readable, actionable refusal reason. It is required
	// because the village emits it unconditionally: every declared refusal on
	// this operation, including the 401 raised by the authentication middleware
	// before the handler runs, is written by one helper that always sets this
	// field. Declaring it optional would understate what the server guarantees
	// and force a consumer to handle an absence that cannot occur.
	//
	// The tag is load-bearing rather than decorative. Go-tag requiredness is
	// applied to catalogued types by the Types generator; this type is
	// deliberately operation-scoped and outside that catalog, so the tag is the
	// only thing that emits the required array here.
	Error string `json:"error" required:"true"`
}

TranscriptUpdateErrorResponse is the body the owner update operation returns on every refusal. The village serves one uniform error envelope, so each declared non-success status carries this same shape and a client reads the reason from one field regardless of which refusal it hit.

It lives here, operation-scoped, rather than in the shared type catalog. The shape is nothing but {error: string}, so promoting it to the canonical cross-language catalog would freeze a transcript-update-specific NAME onto a generic envelope at the next release tag, leaving whoever declares the second operation's refusals to reuse a misleading name, duplicate it, or take a breaking rename. Whether a shared envelope belongs in the catalog is a decision for the change that needs one, not a side effect of this one.

type TypeCatalogEntry

type TypeCatalogEntry struct {
	Name  string
	Value interface{}
}

TypeCatalogEntry is one canonical public Go contract type registered in the language-neutral Types document. It is the production source of truth used by both OpenAPI generation and the TypeScript facade generator.

func TypeCatalogEntries

func TypeCatalogEntries() []TypeCatalogEntry

TypeCatalogEntries returns the complete public wire/domain catalog. Test-only fixture structs and registry/service interfaces deliberately do not belong to this language-neutral contract surface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL