# strictness _(no submodules)_ ## Purpose `strictness` resolves the host's missing-schema policy for the OpenAPI emitter and applies it consistently across every route. It encodes the two-mode contract from the spec: `warn` (emit + warn + count) and `refuse-install` (raise before the plugin is installed). The same helper is wired into both the emitter and the host's plugin-install gate so missing schemas behave identically wherever they're detected. The module also owns the `api.openapi.missing_schema_total` OTel counter — without an OTel meter exporter wired into the host, missing schemas silently accumulate. Surfacing them as a per-plugin per-route labelled metric makes drift visible to anyone watching the observability stack. ## Features - `resolveStrictness({ configured, environment })` — typed precedence resolver. Configured value wins; otherwise `"production"` → refuse, `"development"`/anything else → warn. - `reportMissingSchema(input)` — single chokepoint that either throws or logs+counts. Accepts an injectable logger and counter so test setups can assert exact behaviour with a real `MeterProvider`. - `getMissingSchemaCounter()` — lazy accessor over the package meter so production callers do not need to thread the counter through. ## Usage: Basic ```ts import { reportMissingSchema, resolveStrictness, } from "@suaveplan/api-openapi/strictness"; const mode = resolveStrictness({ environment: "production" }); // "refuse-install" reportMissingSchema({ mode, plugin: "billing", method: "GET", path: "/invoices/:id", slot: "response", }); // throws OpenAPIError(OPENAPI.MISSING_SCHEMA) ``` ## Usage: Advanced ```ts import { MeterProvider } from "@opentelemetry/sdk-metrics"; import { metrics } from "@opentelemetry/api"; import { __resetMissingSchemaCounter, reportMissingSchema, } from "@suaveplan/api-openapi/strictness"; const provider = new MeterProvider(); metrics.setGlobalMeterProvider(provider); __resetMissingSchemaCounter(); const logger = { warn: (msg: string) => console.warn(msg) } as const; reportMissingSchema({ mode: "warn", plugin: "billing", method: "POST", path: "/invoices", slot: "request", logger, }); // → counter increments, logger.warn called ``` ## API Reference - `StrictnessMode` — `"warn" | "refuse-install"`. - `HostEnvironment` — `"development" | "production"`. - `resolveStrictness(input) → StrictnessMode`. - `reportMissingSchema(input) → void` (throws on `refuse-install`). - `getMissingSchemaCounter() → Counter`. - `__resetMissingSchemaCounter()` — test-only seam. - Constants: `MISSING_SCHEMA_COUNTER_NAME`, `OPENAPI_METER_NAME`. ## Implementation Notes - The counter is acquired lazily so registering the package side-effect does not require an OTel SDK at import time. Tests reset the cache via `__resetMissingSchemaCounter()` before binding a fresh `MeterProvider`. - The counter labels — `plugin`, `route`, `slot` — match the spec's scenario assertion (`{ plugin, route }`) and add `slot` so request vs response misses can be distinguished without a second metric. - `LoggerLike.warn` is optional in the contract (`@suaveplan/types`); the call is guarded with optional chaining so structured loggers that only ship `info` + `error` still work.