# `tenant` _(no submodules)_ ## Purpose Provides `buildTenantPluginMiddleware`, the Hono middleware factory the plugin installs on `ctx.app` during `onInit`. The factory composes `createTenantMiddleware` from `@suaveplan/api-tenant` (the canonical resolver + status-gate implementation) with an outer wrapper that records OTel resolution timing and outcome for every request. The result is a single middleware that handles per-request tenant resolution, fail-closed behaviour, and observability. ## Features - Delegates the core resolution + status-gate (`deleted` / `suspended` / `pending`) to the well-tested `@suaveplan/api-tenant` middleware. - Wraps every invocation with `performance.now()` timing so the OTel histogram captures real latency, including the inner middleware's work. - Records `tenant_plugin.resolutions_total{outcome, strategy}` with outcomes `resolved`, `missing`, `error` so dashboards can break down failures by strategy. - Returns the inner middleware's response verbatim — no shape changes — so error handlers see the same `TenantError` they would see if they called `createTenantMiddleware` directly. ## Usage: Basic Example ```ts import { buildTenantPluginMiddleware } from "@suaveplan/api-plugin-tenant"; import { headerResolver } from "@suaveplan/api-tenant"; import { Hono } from "hono"; const resolver = headerResolver("x-tenant-id", lookupFn); const app = new Hono(); app.use("*", buildTenantPluginMiddleware({ resolver, required: false, allowSuspended: false, })); ``` ## Usage: Advanced Example ```ts import { buildTenantPluginMiddleware } from "@suaveplan/api-plugin-tenant"; import { chainResolvers, headerResolver, subdomainResolver, TenantCache } from "@suaveplan/api-tenant"; const resolver = TenantCache.wrap( chainResolvers( headerResolver("x-tenant-id", store.byId), subdomainResolver("app.example.com", store.bySlug) ), { ttlMs: 60_000, negativeTtlMs: 5_000, maxEntries: 10_000 } ); app.use("*", buildTenantPluginMiddleware({ resolver, required: true, allowSuspended: false, excludePaths: ["/health", "/ready", "/openapi.json", "/public"], })); ``` ## API Reference - `interface BuildTenantPluginMiddlewareOptions` — `{ resolver, required, allowSuspended, excludePaths? }`. - `function buildTenantPluginMiddleware(options): MiddlewareHandler` — returns a Hono `MiddlewareHandler` ready for `app.use("*", ...)`. ## Implementation Notes Timing is recorded for every code path including the rethrow path so the histogram captures slow failures (network errors in the store, slow JWT verifications, etc.). The outer wrapper does not call `next()` directly — that responsibility stays inside `createTenantMiddleware`, which also owns the short-circuit for `excludePaths`. Splitting responsibilities this way means a future upgrade of `@suaveplan/api-tenant` (e.g. adding sampling or distributed tracing) lands automatically without changes to the plugin.