openapi

package
v0.1.3-rc1 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 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, group- scoped transcript discovery and pull operations, collectives, contributions, review actions, and linked repositories.

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